mmm-mode-0.5.1/0000775000175000017500000000000012114107240010220 500000000000000mmm-mode-0.5.1/stamp-vti0000664000175000017500000000014312114107240012005 00000000000000@set UPDATED 28 October 2012 @set UPDATED-MONTH October 2012 @set EDITION 0.5.1 @set VERSION 0.5.1 mmm-mode-0.5.1/mmm-mason.el0000664000175000017500000001240312106045412012366 00000000000000;;; mmm-mason.el --- MMM submode class for Mason components ;; Copyright (C) 2000 by Michael Abraham Shulman ;; Author: Michael Abraham Shulman ;;{{{ GPL ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file contains the definition of an MMM Mode submode class for ;; editing Mason components. See the file README.Mason for more ;; details. ;;; Code: (require 'mmm-compat) (require 'mmm-vars) (require 'mmm-auto) ;;{{{ Perl Tags (defvar mmm-mason-perl-tags '("perl" "init" "cleanup" "once" "filter" "shared" "perl_init" "perl_cleanup" "perl_once" "perl_filter")) (defvar mmm-mason-pseudo-perl-tags '("args" "perl_args" "attr" "flags")) (defvar mmm-mason-non-perl-tags '("doc" "perl_doc" "text" "perl_text" "def" "perl_def" "method")) (defvar mmm-mason-perl-tags-regexp (concat "<%" (mmm-regexp-opt mmm-mason-perl-tags t) ">") "Matches tags beginning Mason sections containing Perl code. Saves the name of the tag matched.") (defvar mmm-mason-pseudo-perl-tags-regexp (concat "<%" (mmm-regexp-opt mmm-mason-pseudo-perl-tags t) ">") "Match tags beginning Mason sections that look like Perl but aren't. Saves the name of the tag matched.") (defvar mmm-mason-tag-names-regexp (regexp-opt (append mmm-mason-perl-tags mmm-mason-non-perl-tags) t) "Matches any Mason tag name after the \"<%\". Used to verify that a \"<%\" sequence starts an inline section.") (defun mmm-mason-verify-inline () (not (looking-at mmm-mason-tag-names-regexp))) ;;}}} ;;{{{ Add Classes (mmm-add-group 'mason `((mason-text :submode nil :front "<%text>" :back "" :insert ((?t mason-<%text> nil @ "<%text>" @ "\n" _ "\n" @ "" @))) (mason-doc :submode text-mode :face mmm-comment-submode-face :front "<%doc>" :back "" :face nil :insert ((?d mason-<%doc> nil @ "<%doc>" @ "\n" _ "\n" @ "" @))) (mason-perl :submode perl :match-face (("<%perl>" . mmm-code-submode-face) ("<%init>" . mmm-init-submode-face) ("<%cleanup>" . mmm-cleanup-submode-face) ("<%once>" . mmm-init-submode-face) ("<%filter>" . mmm-special-submode-face) ("<%shared>" . mmm-init-submode-face)) :front ,mmm-mason-perl-tags-regexp :back "" :save-matches 1 :match-name "~1" :save-name 1 :insert ((?, mason-<%TAG> "Perl section: " @ "<%" str ">" @ ";\n" _ "\n" @ "" @) (?< mason-<%TAG> ?, . nil) (?p mason-<%perl> ?, . "perl") (?i mason-<%init> ?, . "init") (?c mason-<%cleanup> ?, . "cleanup") (?o mason-<%once> ?, . "once") (?l mason-<%filter> ?, . "filter") (?s mason-<%shared> ?, . "shared"))) (mason-pseudo-perl :submode perl :face mmm-declaration-submode-face :front ,mmm-mason-pseudo-perl-tags-regexp :back "" :save-matches 1 :insert ((?. mason-pseudo-<%TAG> "Pseudo-perl section: " @ "<%" str ">" @ "\n" _ "\n" @ "" @) (?> mason-pseudo-<%TAG> ?, . nil) (?a mason-<%args> ?. . "args") (?f mason-<%flags> ?. . "flags") (?r mason-<%attr> ?. . "attr"))) (mason-inline :submode perl :face mmm-output-submode-face :front "<%" :front-verify mmm-mason-verify-inline :back "%>" :insert ((?% mason-<%-%> nil @ "<%" @ " " _ " " @ "%>" @) (?5 mason-<%-%> ?% . nil))) (mason-call :submode perl :face mmm-special-submode-face :front "<&" :back "&>" :insert ((?& mason-<&-&> nil @ "<&" @ " " _ " " @ "&>" @) (?7 mason-<&-&> ?% . nil))) (mason-one-line-comment :submode text-mode :face mmm-comment-submode-face :front "^%#" :back "\n" :insert ((?# mason-%-comment nil (mmm-mason-start-line) @ "%" @ "# " _ @ '(mmm-mason-end-line) "\n" @) (?3 mason-%-comment ?# . nil))) (mason-one-line :submode perl :face mmm-code-submode-face :front "^%" :back "\n" :insert ((return mason-%-line nil (mmm-mason-start-line) @ "%" @ " " _ @ '(mmm-mason-end-line) "\n" @))))) ;;}}} ;;{{{ One-line Sections (defun mmm-mason-start-line () (if (bolp) "" "\n")) (defun mmm-mason-end-line () (if (eolp) (delete-char 1))) ;;}}} ;;{{{ Set Mode Line (defun mmm-mason-set-mode-line () (setq mmm-buffer-mode-display-name "Mason")) (add-hook 'mmm-mason-class-hook 'mmm-mason-set-mode-line) ;;}}} (provide 'mmm-mason) ;;; mmm-mason.el ends here mmm-mode-0.5.1/elisp-comp0000775000175000017500000000371512043063215012150 00000000000000#!/bin/sh # Copyright (C) 1995 Free Software Foundation, Inc. # François Pinard , 1995. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # This script byte-compiles all `.el' files which are part of its # arguments, using GNU Emacs, and put the resulting `.elc' files into # the current directory, so disregarding the original directories used # in `.el' arguments. # # This script manages in such a way that all Emacs LISP files to # be compiled are made visible between themselves, in the event # they require or load-library one another. # This script was modified by Michael Abraham Shulman # not to create a temporary directory, so # that elisp files not given on the command line at the same time, # the way Automake *actually* uses this script, can load each other. if test $# = 0; then echo 1>&2 "No files given to $0" exit 1 else if test -z "$EMACS" || test "$EMACS" = "t"; then # Value of "t" means we are running in a shell under Emacs. # Just assume Emacs is called "emacs". EMACS=emacs fi # tempdir=elc.$$ # mkdir $tempdir # cp $* $tempdir # cd $tempdir # echo "elisp-comp called on $*" echo "(setq load-path (cons nil load-path))" > script $EMACS -q -batch -l script -f batch-byte-compile $* # mv *.elc .. # cd .. # rm -fr $tempdir fi mmm-mode-0.5.1/configure0000775000175000017500000031704212114107236012063 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= PACKAGE_URL= ac_subst_vars='LTLIBOBJS LIBOBJS EMACS_VERSION lispdir EMACSLOADPATH EMACS am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking with_xemacs with_emacs with_lispdir ' ac_precious_vars='build_alias host_alias target_alias EMACS EMACSLOADPATH' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-xemacs Use XEmacs to build --with-emacs Use Emacs to build --with-lispdir override the default lisp directory Some influential environment variables: EMACS the Emacs editor command EMACSLOADPATH the Emacs library search path Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am__api_version='1.11' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE=mmm-mode VERSION=0.5.1 cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' if test "${EMACS}" = "t"; then EMACS="" fi # Check whether --with-xemacs was given. if test "${with_xemacs+set}" = set; then : withval=$with_xemacs; if test "${withval}" = "yes"; then EMACS=xemacs; else EMACS=${withval}; fi fi # Check whether --with-emacs was given. if test "${with_emacs+set}" = set; then : withval=$with_emacs; if test "${withval}" = "yes"; then EMACS=emacs; else EMACS=${withval}; fi fi # Extract the first word of "xemacs", so it can be a program name with args. set dummy xemacs; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_EMACS+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$EMACS"; then ac_cv_prog_EMACS="$EMACS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_EMACS="xemacs" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_EMACS" && ac_cv_prog_EMACS="emacs" fi fi EMACS=$ac_cv_prog_EMACS if test -n "$EMACS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $EMACS" >&5 $as_echo "$EMACS" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # If set to t, that means we are running in a shell under Emacs. # If you have an Emacs named "t", then use the full path. test x"$EMACS" = xt && EMACS= for ac_prog in emacs xemacs do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_EMACS+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$EMACS"; then ac_cv_prog_EMACS="$EMACS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_EMACS="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi EMACS=$ac_cv_prog_EMACS if test -n "$EMACS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $EMACS" >&5 $as_echo "$EMACS" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$EMACS" && break done test -n "$EMACS" || EMACS="no" # Check whether --with-lispdir was given. if test "${with_lispdir+set}" = set; then : withval=$with_lispdir; lispdir="$withval" { $as_echo "$as_me:${as_lineno-$LINENO}: checking where .elc files should go" >&5 $as_echo_n "checking where .elc files should go... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lispdir" >&5 $as_echo "$lispdir" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking where .elc files should go" >&5 $as_echo_n "checking where .elc files should go... " >&6; } if ${am_cv_lispdir+:} false; then : $as_echo_n "(cached) " >&6 else if test $EMACS != "no"; then if test x${lispdir+set} != xset; then # If $EMACS isn't GNU Emacs or XEmacs, this can blow up pretty badly # Some emacsen will start up in interactive mode, requiring C-x C-c to exit, # which is non-obvious for non-emacs users. # Redirecting /dev/null should help a bit; pity we can't detect "broken" # emacsen earlier and avoid running this altogether. { { $as_echo "$as_me:${as_lineno-$LINENO}: \$EMACS -batch -q -eval '(while load-path (princ (concat (car load-path) \"\\n\")) (setq load-path (cdr load-path)))' conftest.out"; } >&5 ($EMACS -batch -q -eval '(while load-path (princ (concat (car load-path) "\n")) (setq load-path (cdr load-path)))' conftest.out) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } am_cv_lispdir=`sed -n \ -e 's,/$,,' \ -e '/.*\/lib\/x*emacs\/site-lisp$/{s,.*/lib/\(x*emacs/site-lisp\)$,${libdir}/\1,;p;q;}' \ -e '/.*\/share\/x*emacs\/site-lisp$/{s,.*/share/\(x*emacs/site-lisp\),${datarootdir}/\1,;p;q;}' \ conftest.out` rm conftest.out fi fi test -z "$am_cv_lispdir" && am_cv_lispdir='${datadir}/emacs/site-lisp' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_lispdir" >&5 $as_echo "$am_cv_lispdir" >&6; } lispdir="$am_cv_lispdir" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for emacs version" >&5 $as_echo_n "checking for emacs version... " >&6; } elisp="(and (boundp 'emacs-major-version) (format \"%d.%d\" emacs-major-version emacs-minor-version))" if test -z ""noecho""; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for version" >&5 $as_echo_n "checking for version... " >&6; } fi if ${EMACS_cv_SYS_version+:} false; then : $as_echo_n "(cached) " >&6 else OUTPUT=./conftest-$$ echo ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x) (prin1-to-string x)) nil \"${OUTPUT}\"))" >& 5 2>&1 ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x 'ignore) (prin1-to-string x)) nil \"${OUTPUT}\"nil 5))" >& 5 2>&1 retval=`cat ${OUTPUT}` echo "=> ${retval}" >& 5 2>&1 rm -f ${OUTPUT} EMACS_cv_SYS_version=$retval fi version=${EMACS_cv_SYS_version} if test -z ""noecho""; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $version" >&5 $as_echo "$version" >&6; } fi EMACS_VERSION=${EMACS_cv_SYS_version} { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${EMACS_VERSION}" >&5 $as_echo "${EMACS_VERSION}" >&6; } ac_config_files="$ac_config_files Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" eval set X " :F $CONFIG_FILES " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi mmm-mode-0.5.1/install-sh0000775000175000017500000001273612043063215012161 00000000000000#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 mmm-mode-0.5.1/mmm-auto.el0000664000175000017500000001510212111524516012223 00000000000000;;; mmm-auto.el --- loading and enabling MMM Mode automatically ;; Copyright (C) 2000 by Michael Abraham Shulman ;; Author: Michael Abraham Shulman ;;{{{ GPL ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file contains functions and hooks to load and enable MMM Mode ;; automatically. It sets up autoloads for the main MMM Mode functions ;; and interactive commands, and also sets up MMM Global Mode. ;;{{{ Comments on MMM Global Mode ;; This is a kludge borrowed from `global-font-lock-mode'. The idea ;; is the same: we have a function (here `mmm-mode-on-maybe') that we ;; want to be run whenever a major mode starts. Unfortunately, there ;; is no hook (like, say `major-mode-hook') that all major modes run ;; when they are finished. `post-command-hook', however, is run after ;; *every* command, so we do our work in there. (Actually, using ;; `post-command-hook' is even better than being run by major mode ;; functions, since it is run after all local variables and text are ;; loaded, which may not be true in certain cases for the other.) ;; In order to do this magic, we rely on the fact that there *is* a ;; hook that all major modes run when *beginning* their work. They ;; call `kill-all-local-variables' (unless they are broken), which in ;; turn runs `change-major-mode-hook'. So we add a function to *that* ;; hook which saves the current buffer and temporarily adds a function ;; to `post-command-hook' which processes that buffer. ;; Actually, in the interests of generality, what that function does ;; is run the hook `mmm-major-mode-hook'. Our desired function ;; `mmm-mode-on-maybe' is then added to that hook. This way, if the ;; user wants to run something else on every major mode, they can just ;; add it to `mmm-major-mode-hook' and take advantage of this hack. ;;}}} ;;; Code: (require 'cl) (require 'mmm-vars) ;;{{{ Autoload Submode Classes (defvar mmm-autoloaded-classes '((mason "mmm-mason" nil) (myghty "mmm-myghty" nil) (html-css "mmm-sample" nil) (html-js "mmm-sample" nil) (here-doc "mmm-sample" nil) (embperl "mmm-sample" nil) (eperl "mmm-sample" nil) (jsp "mmm-sample" nil) (file-variables "mmm-sample" nil) (rpm-sh "mmm-rpm" t) (rpm "mmm-rpm" nil) (cweb "mmm-cweb" nil) (sgml-dtd "mmm-sample" nil) (noweb "mmm-noweb" nil) (html-php "mmm-sample" nil) ) "Alist of submode classes autoloaded from files. Elements look like \(CLASS FILE PRIVATE) where CLASS is a submode class symbol, FILE is a string suitable for passing to `load', and PRIVATE is non-nil if the class is invisible to the user. Classes can be added to this list with `mmm-autoload-class'.") (defun mmm-autoload-class (class file &optional private) "Autoload submode class CLASS from file FILE. PRIVATE, if non-nil, means the class is user-invisible. In general, private classes need not be autoloaded, since they will usually be invoked by a public class in the same file." ;; Don't autoload already defined classes (unless (assq class mmm-classes-alist) (add-to-list 'mmm-autoloaded-classes (list class file private)))) ;;}}} ;;{{{ Autoload Functions ;; To shut up the byte compiler. (eval-and-compile (autoload 'mmm-mode-on "mmm-mode" "Turn on MMM Mode. See `mmm-mode'.") (autoload 'mmm-mode-off "mmm-mode" "Turn off MMM Mode. See `mmm-mode'.") (autoload 'mmm-update-font-lock-buffer "mmm-region") (autoload 'mmm-ensure-fboundp "mmm-utils") (autoload 'mmm-mode "mmm-mode" "Minor mode to allow multiple major modes in one buffer. Without ARG, toggle MMM Mode. With ARG, turn MMM Mode on iff ARG is positive and off otherwise." t)) ;; These may actually be used. (autoload 'mmm-ify-by-class "mmm-cmds" "" t) (autoload 'mmm-ify-by-regexp "mmm-cmds" "" t) (autoload 'mmm-ify-region "mmm-cmds" "" t) (autoload 'mmm-parse-buffer "mmm-cmds" "" t) (autoload 'mmm-parse-region "mmm-cmds" "" t) (autoload 'mmm-parse-block "mmm-cmds" "" t) (autoload 'mmm-clear-current-region "mmm-cmds" "" t) (autoload 'mmm-reparse-current-region "mmm-cmds" "" t) (autoload 'mmm-end-current-region "mmm-cmds" "" t) (autoload 'mmm-insertion-help "mmm-cmds" "" t) (autoload 'mmm-insert-region "mmm-cmds" "" t) ;;}}} ;;{{{ MMM Global Mode (defvar mmm-changed-buffers-list () "Buffers that need to be checked for running the major mode hook.") (defun mmm-major-mode-change () "Add this buffer to `mmm-changed-buffers-list' for checking. When the current command is over, MMM Mode will be turned on in this buffer depending on the value of `mmm-global-mode'. Actually, everything in `mmm-major-mode-hook' will be run." (and (boundp 'mmm-mode) mmm-mode (mmm-mode-off)) (add-to-list 'mmm-changed-buffers-list (current-buffer)) (add-hook 'post-command-hook 'mmm-check-changed-buffers)) (add-hook 'change-major-mode-hook 'mmm-major-mode-change) (defun mmm-check-changed-buffers () "Run major mode hook for the buffers in `mmm-changed-buffers-list'." (remove-hook 'post-command-hook 'mmm-check-changed-buffers) (dolist (buffer mmm-changed-buffers-list) (when (buffer-live-p buffer) (with-current-buffer buffer (mmm-run-major-mode-hook)))) (setq mmm-changed-buffers-list '())) (defun mmm-mode-on-maybe () "Conditionally turn on MMM Mode. Turn on MMM Mode if `mmm-global-mode' is non-nil and there are classes to apply, or always if `mmm-global-mode' is t." (cond ((eq mmm-global-mode t) (mmm-mode-on)) ((not mmm-global-mode)) ((mmm-get-all-classes nil) (mmm-mode-on))) (when mmm-mode (mmm-update-font-lock-buffer))) (add-hook 'mmm-major-mode-hook 'mmm-mode-on-maybe) (defalias 'mmm-add-find-file-hooks 'mmm-add-find-file-hook) (defun mmm-add-find-file-hook () "Equivalent to \(setq mmm-global-mode 'maybe). This function is deprecated and may be removed in future." (message "Warning: `mmm-add-find-file-hook' is deprecated.") (setq mmm-global-mode 'maybe)) ;;}}} (provide 'mmm-auto) ;;; mmm-auto.el ends here mmm-mode-0.5.1/mmm-univ.el0000664000175000017500000000360212106045667012247 00000000000000;;; mmm-univ.el --- The "Universal" Submode Class ;; Copyright (C) 2000 by Free Software Foundation, Inc. ;; Author: Michael Abraham Shulman ;;{{{ GPL ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file defines the "universal" submode class, the default value ;; of `mmm-global-classes', which specifies a standard way to indicate ;; that part of a buffer should be in a different mode--for example, ;; in an email message. ;;; Code: (require 'mmm-auto) (require 'mmm-vars) (defun mmm-univ-get-mode (string) (string-match "[a-zA-Z-]+" string) (setq string (match-string 0 string)) (let ((modestr (intern (if (string-match "mode\\'" string) string (concat string "-mode"))))) (or (mmm-ensure-modename modestr) (signal 'mmm-no-matching-submode nil)))) (mmm-add-classes `((universal :front "{%\\([a-zA-Z-]+\\)%}" :back "{%/~1%}" :insert ((?/ universal "Submode: " @ "{%" str "%}" @ "\n" _ "\n" @ "{%/" str "%}" @)) :match-submode mmm-univ-get-mode :save-matches 1 ))) (provide 'mmm-univ) ;;; Local Variables: ;;; mmm-global-classes: nil ;;; End: ;;; mmm-univ.el ends here mmm-mode-0.5.1/mkinstalldirs0000775000175000017500000000122712106045340012753 00000000000000#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here mmm-mode-0.5.1/README0000664000175000017500000000740612105043137011033 00000000000000 MMM Mode for Emacs ================== OVERVIEW MMM Mode is a minor mode for Emacs that allows Multiple Major Modes to coexist in one buffer. It is well-suited to editing: * Preprocessed code, such as server-side Ruby, Perl or PHP embedded in HTML * Code generating code, such as HTML output by CGI scripts * Embedded code, such as Javascript in HTML * Literate programming: code interspersed with documentation, e.g. Noweb INSTALLATION Use any of the following options: 1. Users of package.el (a.k.a. ELPA) can easily install MMM Mode from the Melpa package repository at http://melpa.milkbox.net/ -- this is the preferred and best-supported installation mechanism. 2. Since currently MMM Mode is written in pure Emacs Lisp, you could just copy all the *.el files in the distribution to a directory in your `load-path', and optionally byte-compile them manually (see the Emacs Manual). The configure installation also installs the MMM Mode info manual in your site info directory, so if you're installing manually, you might want to do that too. 3. MMM Mode has a standard GNU configure-driven installation. (See the file INSTALL for generic instructions, most of which don't apply.) To install in the standard locations, unpack the archive, `cd' to the mmm-mode-X.X.X directory created, and run these commands: ./autogen.sh ./configure make make install If you have more than one version of emacs installed and want to use MMM in a version other than /usr/bin/emacs, you must set the environment variable EMACS before running `configure', e.g. EMACS=/usr/bin/xemacs ./configure make make install If you want to use MMM in more than one version of emacs, you must either have separate site-lisp directories (such as Debian does), or load it from source every time; byte-compiled files are not portable between emacsen. CONFIGURATION Once MMM Mode is installed, it has to be configured correctly. This can be done in a site-start file or in user's initialization files; usually the latter is preferable, except possibly for autoloads. First the package needs to be loaded, with either (require 'mmm-mode) or instead, to save time during emacs startup, (require 'mmm-auto) Then you will probably want to set something like this: (setq mmm-global-mode 'maybe) (mmm-add-mode-ext-class 'html-mode "\\.php\\'" 'html-php) The first line tells MMM Mode to load itself whenever you open an appropriate file, and the second is an example which says to notice PHP regions in html-mode files having a `.php' extension. Both lines are necessary. You will, of course, want to change and duplicate the second line according to your needs. either of the first two parameters can be `nil', meaning not to consider that criterion. For example, if all your html files, regardless of extension, are Mason components, you will want something like: (mmm-add-mode-ext-class 'html-mode nil 'mason) whereas if all your files with a `.nw' extension, regardless of primary mode (some may be LaTeX, others HTML, say) are Noweb, you will prefer (mmm-add-mode-ext-class nil "\\.nw\\'" 'noweb) See the info file for more extensive documentation, and for other configuration options. DOCUMENTATION For further information, see (in order) the accompanying info file, the documentation strings of functions and variables, the comments in the source code, and the source code itself. UPDATES The latest version of MMM Mode should always be available from https://github.com/purcell/mmm-mode FEEDBACK Bug reports, suggestions and questions can be submitted at https://github.com/purcell/mmm-mode/issues. Thanks for using MMM Mode! mmm-mode-0.5.1/acinclude.m40000664000175000017500000001174112043063215012341 00000000000000dnl dnl Execute arbitrary emacs lisp dnl AC_DEFUN(AC_EMACS_LISP, [ elisp="$2" if test -z "$3"; then AC_MSG_CHECKING(for $1) fi AC_CACHE_VAL(EMACS_cv_SYS_$1,[ OUTPUT=./conftest-$$ echo ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x) (prin1-to-string x)) nil \"${OUTPUT}\"))" >& AC_FD_CC 2>&1 ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x 'ignore) (prin1-to-string x)) nil \"${OUTPUT}\"nil 5))" >& AC_FD_CC 2>&1 retval=`cat ${OUTPUT}` echo "=> ${retval}" >& AC_FD_CC 2>&1 rm -f ${OUTPUT} EMACS_cv_SYS_$1=$retval ]) $1=${EMACS_cv_SYS_$1} if test -z "$3"; then AC_MSG_RESULT($$1) fi ]) AC_DEFUN(AC_XEMACS_P, [ AC_MSG_CHECKING([if $EMACS is really XEmacs]) AC_EMACS_LISP(xemacsp,(if (string-match \"XEmacs\" emacs-version) \"yes\" \"no\") ,"noecho") XEMACS=${EMACS_cv_SYS_xemacsp} EMACS_FLAVOR=emacs if test "$XEMACS" = "yes"; then EMACS_FLAVOR=xemacs fi AC_MSG_RESULT($XEMACS) AC_SUBST(XEMACS) AC_SUBST(EMACS_FLAVOR) ]) AC_DEFUN(AC_PATH_LISPDIR, [ AC_XEMACS_P if test "$prefix" = "NONE"; then AC_MSG_CHECKING([prefix for your Emacs]) AC_EMACS_LISP(prefix,(expand-file-name \"..\" invocation-directory),"noecho") prefix=${EMACS_cv_SYS_prefix} AC_MSG_RESULT($prefix) fi AC_ARG_WITH(lispdir, --with-lispdir Where to install lisp files, lispdir=${withval}) AC_MSG_CHECKING([where .elc files should go]) if test -z "$lispdir"; then dnl Set default value theprefix=$prefix if test "x$theprefix" = "xNONE"; then theprefix=$ac_default_prefix fi lispdir="\$(datadir)/${EMACS_FLAVOR}/site-lisp" for thedir in share lib; do potential= if test -d ${theprefix}/${thedir}/${EMACS_FLAVOR}/site-lisp; then lispdir="\$(prefix)/${thedir}/${EMACS_FLAVOR}/site-lisp" break fi done fi AC_MSG_RESULT($lispdir) AC_SUBST(lispdir) ]) dnl dnl Determine the emacs version we are running. dnl Automatically substitutes @EMACS_VERSION@ with this number. dnl AC_DEFUN(AC_EMACS_VERSION, [ AC_MSG_CHECKING(for emacs version) AC_EMACS_LISP(version,(and (boundp 'emacs-major-version) (format \"%d.%d\" emacs-major-version emacs-minor-version)),"noecho") EMACS_VERSION=${EMACS_cv_SYS_version} AC_SUBST(EMACS_VERSION) AC_MSG_RESULT(${EMACS_VERSION}) ]) dnl dnl Determine whether the specified version of Emacs supports packages dnl or not. Currently, only XEmacs 20.3 does, but this is a general dnl check. dnl AC_DEFUN(AC_EMACS_PACKAGES, [ AC_ARG_WITH(package-dir, --with-package-dir Configure as a XEmacs package in directory, [ EMACS_PACKAGE_DIR="${withval}"]) if test -n "$EMACS_PACKAGE_DIR"; then if test "$prefix" != "NONE"; then AC_MSG_ERROR([--with-package-dir and --prefix are mutually exclusive]) fi dnl Massage everything to use $(prefix) correctly. prefix=$EMACS_PACKAGE_DIR datadir='$(prefix)/etc/w3' infodir='$(prefix)/info' lispdir='$(prefix)/lisp/w3' fi AC_SUBST(EMACS_PACKAGE_DIR) ]) dnl dnl Check whether a function exists in a library dnl All '_' characters in the first argument are converted to '-' dnl AC_DEFUN(AC_EMACS_CHECK_LIB, [ if test -z "$3"; then AC_MSG_CHECKING(for $2 in $1) fi library=`echo $1 | tr _ -` AC_EMACS_LISP($1,(progn (fmakunbound '$2) (condition-case nil (progn (require '$library) (fboundp '$2)) (error (prog1 nil (message \"$library not found\"))))),"noecho") if test "${EMACS_cv_SYS_$1}" = "nil"; then EMACS_cv_SYS_$1=no fi if test "${EMACS_cv_SYS_$1}" = "t"; then EMACS_cv_SYS_$1=yes fi HAVE_$1=${EMACS_cv_SYS_$1} AC_SUBST(HAVE_$1) if test -z "$3"; then AC_MSG_RESULT($HAVE_$1) fi ]) dnl dnl Check whether a variable exists in a library dnl All '_' characters in the first argument are converted to '-' dnl AC_DEFUN(AC_EMACS_CHECK_VAR, [ AC_MSG_CHECKING(for $2 in $1) library=`echo $1 | tr _ -` AC_EMACS_LISP($1,(progn (makunbound '$2) (condition-case nil (progn (require '$library) (boundp '$2)) (error nil))),"noecho") if test "${EMACS_cv_SYS_$1}" = "nil"; then EMACS_cv_SYS_$1=no fi HAVE_$1=${EMACS_cv_SYS_$1} AC_SUBST(HAVE_$1) AC_MSG_RESULT($HAVE_$1) ]) dnl dnl Perform sanity checking and try to locate the custom and widget packages dnl AC_DEFUN(AC_CHECK_CUSTOM, [ AC_MSG_CHECKING(for acceptable custom library) AC_CACHE_VAL(EMACS_cv_ACCEPTABLE_CUSTOM,[ AC_EMACS_CHECK_LIB(widget,widget-convert-text,"noecho") AC_EMACS_CHECK_LIB(wid_edit,widget-convert-text,"noecho") if test "${HAVE_widget}" = "yes"; then EMACS_cv_ACCEPTABLE_CUSTOM=yes else if test "${HAVE_wid_edit}" != "no"; then EMACS_cv_ACCEPTABLE_CUSTOM=yes else EMACS_cv_ACCEPTABLE_CUSTOM=no fi fi if test "${EMACS_cv_ACCEPTABLE_CUSTOM}" = "yes"; then AC_EMACS_LISP(widget_dir,(file-name-directory (locate-library \"widget\")),"noecho") EMACS_cv_ACCEPTABLE_CUSTOM=$EMACS_cv_SYS_widget_dir fi ]) AC_ARG_WITH(custom, --with-custom Specify where to find the custom package, [ EMACS_cv_ACCEPTABLE_CUSTOM=`( cd $withval && pwd || echo "$withval" ) 2> /dev/null` ]) CUSTOM=${EMACS_cv_ACCEPTABLE_CUSTOM} AC_SUBST(CUSTOM) AC_MSG_RESULT("${CUSTOM}") ]) mmm-mode-0.5.1/mmm-cweb.el0000664000175000017500000000522712106045266012206 00000000000000;;; mmm-cweb.el --- MMM submode class for CWeb programs ;; Copyright (C) 2001 by Alan Shutko ;; Author: Alan Shutko ;;{{{ GPL ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file contains the definition of an MMM Mode submode class for ;; editing CWeb programs. ;;; Code: (require 'mmm-compat) (require 'mmm-vars) (require 'mmm-auto) (defvar mmm-cweb-section-tags '("@ " "@*")) (defvar mmm-cweb-section-regexp (concat "^" (mmm-regexp-opt mmm-cweb-section-tags t))) (defvar mmm-cweb-c-part-tags '("@c" "@>=" "@>+=" "@p")) (defvar mmm-cweb-c-part-regexp (concat (mmm-regexp-opt mmm-cweb-c-part-tags t))) (defun mmm-cweb-in-limbo (pos) "Check to see if POS is in limbo, ie before any cweb sections." (save-match-data (save-excursion (goto-char pos) (not (re-search-backward mmm-cweb-section-regexp nil t))))) (defun mmm-cweb-verify-brief-c () "Verify function for cweb-brief-c class. Checks whether the match is in limbo." (not (mmm-cweb-in-limbo (match-beginning 0)))) (mmm-add-group 'cweb `( (cweb-c-part :submode c-mode :front ,mmm-cweb-c-part-regexp :back ,mmm-cweb-section-regexp) (cweb-label :submode tex-mode :front "@<" :back "@>" :face mmm-comment-submode-face :insert ((?l cweb-label nil @ "@<" @ "@>"))) (cweb-brief-c :submode c-mode :front "[^\\|]\\(|\\)[^|]" :front-match 1 :front-verify mmm-cweb-verify-brief-c ; :front-offset -1 :back "[^\\|]\\(|\\)" :back-match 1 ; :back-offset 1 :end-not-begin t :insert ((?| cweb-c-in-tex nil "|" @ "|"))) (cweb-comment :submode tex-mode :front "/[*]" :back "[*]/" :face mmm-comment-submode-face) )) ;; (add-to-list 'mmm-mode-ext-classes-alist ;; '(plain-tex-mode "\\.w\\'" cweb)) ;; (add-to-list 'mmm-mode-ext-classes-alist ;; '(latex-mode "\\.w\\'" cweb)) ;; (add-to-list 'auto-mode-alist '("\\.w\\'" . tex-mode)) (provide 'mmm-cweb) ;;; mmm-cweb.el ends here mmm-mode-0.5.1/missing0000775000175000017500000002403212043063215011544 00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing 0.4 - GNU automake" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then # We have makeinfo, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; tar) shift if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 fi # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 mmm-mode-0.5.1/mmm.info0000664000175000017500000026647712114107240011631 00000000000000This is mmm.info, produced by makeinfo version 4.13 from mmm.texinfo. INFO-DIR-SECTION GNU Emacs Lisp START-INFO-DIR-ENTRY * MMM-Mode: (mmm). Multiple Major Modes for Emacs END-INFO-DIR-ENTRY This is edition 0.5.1 of the MMM Mode Manual, last updated 28 October 2012. It documents version 0.5.1 of MMM Mode. Copyright 2000 Michael Abraham Shulman. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the sections entitled "Copying" and "GNU General Public License" are included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.  File: mmm.info, Node: Top, Next: Overview, Prev: (dir), Up: (dir) MMM Mode ******** MMM Mode is a minor mode for Emacs which allows Multiple Major Modes to coexist in a single buffer. This is edition 0.5.1 of the MMM Mode Manual, last updated 28 October 2012, which documents version 0.5.1 of MMM Mode. * Menu: * Overview:: An overview and introduction to MMM Mode. * Basics:: The basics of how to use it. * Customizing:: Customizing how it works to your needs. * Supplied Classes:: The supplied submode classes. * Writing Classes:: Writing your own submode classes. * Indices:: Just that. --- The Detailed Node Listing --- Overview of MMM Mode * Basic Concepts:: A simple explanation of how it works. * Installation:: How to install MMM Mode. * Quick Start:: Getting started using MMM Mode quickly. MMM Mode Basics * MMM Minor Mode:: The Emacs minor mode that manages it all. * Submode Classes:: What they are and how to use them. * Selecting Classes:: How MMM Mode knows what classes to use. * Insertion:: Inserting new submode regions automatically. * Re-parsing:: Re-scanning for submode regions. * Interactive:: Adding submode regions manually. * Global Mode:: Turning MMM Mode on automatically. The MMM Minor Mode * Enabling MMM Mode:: Turning MMM Mode on and off. * MMM Mode Keys:: Default key bindings in MMM Mode. How MMM Mode selects submode classes * File Classes:: Classes for a single file. * Mode-Ext Classes:: Classes for a given mode or extension. * Global Classes:: Classes for all MMM Mode buffers. MMM Global Mode * Major Mode Hook:: Using MMM's Major Mode Hook Customizing MMM Mode * Region Coloring:: Changing or removing background colors. * Preferred Modes:: Choosing which major modes to use. * Mode Line:: What is displayed in the mode line. * Key Bindings:: Customizing the MMM Mode key bindings. * Local Variables:: What local variables are saved for submodes. * Changing Classes:: Changing the supplied submode classes. * Hooks:: How to make MMM Mode run your code. Supplied Submode Classes * Mason:: Mason server-side Perl in HTML. * File Variables:: Elisp code in File Variables. * Here-documents:: Code in shell and Perl here-documents. * Javascript:: Javascript embedded in HTML. * Embedded CSS:: CSS Styles embedded in HTML. * Embperl:: Another syntax for Perl in HTML. * ePerl:: A general Perl-embedding syntax. * JSP:: Java code embedded in HTML. * RPM:: Shell scripts in RPM Spec Files. * Noweb:: Noweb literate programs. Writing Submode Classes * Basic Classes:: Writing a simple submode class. * Paired Delimiters:: Matching paired delimiters. * Region Placement:: Placing the region more accurately. * Submode Groups:: Grouping several classes together. * Calculated Submodes:: Deciding the submode at run-time. * Calculated Faces:: Deciding the display face at run-time. * Insertion Commands:: Inserting regions automatically. * Region Names:: Naming regions for syntax grouping. * Other Hooks:: Running code at arbitrary points. * Delimiters:: Controlling delimiter overlays. * Misc Keywords:: Other miscellaneous options. Indices * Concept Index:: Index of MMM Mode Concepts. * Function Index:: Index of functions and variables. * Keystroke Index:: Index of key bindings in MMM Mode.  File: mmm.info, Node: Overview, Next: Basics, Prev: Top, Up: Top 1 Overview of MMM Mode ********************** MMM Mode is a minor mode for Emacs which allows Multiple Major Modes to coexist in a single buffer. The name is an abbreviation of `Multiple Major Modes'(1). A major mode is a customization of Emacs for editing a certain type of text, such as code for a specific programming language. *Note Major Modes: (emacs)Major Modes, for details. MMM Mode is a general extension to Emacs which is useful whenever one file contains text in two or more programming languages, or that should be in two or more different modes. For example: * CGI scripts written in any language, from Perl to PL/SQL, may want to output verbatim HTML, and the writer of such scripts may want to use Emacs' html-mode or sgml-mode to edit this HTML code, while remaining in the appropriate programming language mode for the rest of the file. *Note Here-documents::, for example. * There are now many "content delivery systems" which turn the CGI script idea around and simply add extra commands to an HTML file, often in some programming language, which are interpreted on the server. *Note Mason::, *Note Embperl::, *Note ePerl::, *Note JSP::. * HTML itself can also contain embedded languages such as Javascript and CSS styles, for which Emacs has different major modes. *Note Javascript::, and *Note Embedded CSS::, for example. * The idea of "literate programming" requires the same file to contain documentation (written as text, html, latex, etc.) and code (in an appropriate programming language). *Note Noweb::, for example. * Emacs allows files of any type to contain `local variables', which can include Emacs Lisp code to be evaluated. *Note File Variables: (emacs)File Variables. It may be easier to edit this code in Emacs Lisp mode than in whatever mode is used for the rest of the file. *Note File Variables::. * There are many more possible uses for MMM Mode. RPM spec files can contain shell scripts (*note RPM::). Email or newsgroup messages may contain sample code. And so on. We encourage you to experiment. * Menu: * Basic Concepts:: A simple explanation of how it works. * Installation:: How to install MMM Mode. * Quick Start:: Getting started using MMM Mode quickly. ---------- Footnotes ---------- (1) The name is derived from `mmm.el' for XEmacs by Gongquan Chen , from which MMM Mode was adapted.  File: mmm.info, Node: Basic Concepts, Next: Installation, Prev: Overview, Up: Overview 1.1 Basic Concepts ================== The way MMM Mode works is as follows. Each buffer has a "dominant" or "default" major mode, which is chosen as major modes normally are: the user can set it interactively, or it can be chosen automatically with `auto-mode-alist' (*note Choosing Modes: (emacs)Choosing Modes.). Within the file, MMM Mode creates "submode regions" within which other major modes are in effect. While the point is in a submode region, the following changes occur: 1. The local keymap is that of the submode. This means the key bindings for the submode are available, while those of the dominant mode are not. 2. The mode line (*note Mode Line: (emacs)Mode Line.) changes to show which submode region is active. This can be configured; see *note Mode Line::. 3. The major mode menu, both on the menu bar and the mouse popup, are that of the submode. 4. Some local variables of the submode shadow those of the default mode (*note Local Variables::). For the user, this serves to help make Emacs behave as if the submode were the major mode. 5. The syntax table and indentation are those of the submode. 6. Font-lock (*note Font Lock: (emacs)Font Lock.) fontifies correctly for the submode. 7. The submode regions are highlighted by a background color; see *note Region Coloring::. The submode regions are represented internally by Emacs Lisp objects known as "overlays". Some of the above are implemented by overlay properties, and others are updated by an MMM Mode function in `post-command-hook'. You don't need to know this to use MMM Mode, but it may make any error messages you come across more understandable. *Note Overlays: (elisp)Overlays, for more information on overlays. Because overlays are not saved with a file, every time a file is opened, they must be created. Creating submode regions is occasionally referred to as "mmm-ification". (I've never had occasion to pronounce this, but if I did I would probably say `mummification'. Like what they did in ancient Egypt.) You can mmm-ify a buffer interactively, but most often MMM Mode will find and create submode regions automatically based on a buffer's file extension, dominant mode, or local variables.  File: mmm.info, Node: Installation, Next: Quick Start, Prev: Basic Concepts, Up: Overview 1.2 Installing MMM Mode ======================= MMM Mode has a standard installation process. See the file INSTALL for generic information on this process. To summarize, unpack the archive, `cd' to the created MMM Mode directory, type `./configure', then `make', then `make install'. If all goes correctly, this will compile the MMM Mode elisp files, install them in your local site-lisp directory, and install the MMM Mode info file `mmm.info' in your local info directory. Now you need to configure your Emacs initialization file (usually `~/.emacs') to use MMM Mode. First, Emacs has to know where to find MMM Mode. In other words, the MMM Mode directory has to be in `load-path'. This can be done in the parent directory's `subdirs.el' file, or in the init file with a line such as: (add-to-list 'load-path "/path/to/site-lisp/mmm/") Once `load-path' is configured, MMM Mode must be loaded. You can load all of MMM Mode with the line (require 'mmm-mode) but if you use MMM Mode only rarely, it may not be desirable to load all of it at the beginning of every editing session. You can load just enough of MMM Mode so it will turn itself on when necessary and load the rest of itself, by using instead the line (require 'mmm-auto) in your initialization file. One more thing you may want to do right now is to set the variable `mmm-global-mode'. If this variable is `nil' (the default), MMM Mode will never turn itself on. If it is `t', MMM Mode will turn itself on in every buffer. Probably the most useful value for it, however, is the symbol `maybe' (actually, anything that is not `nil' and not `t'), which causes MMM Mode to turn itself on in precisely those buffers where it would be useful. You can do this with a line such as: (setq mmm-global-mode 'maybe) in your initialization file. *Note Global Mode::, for more detailed information.  File: mmm.info, Node: Quick Start, Prev: Installation, Up: Overview 1.3 Getting Started Quickly =========================== Perhaps the simplest way to create submode regions is to do it interactively by specifying a region. First you must turn MMM Mode on--say, with `M-x mmm-mode'--then place point and mark around the area you want to make into a submode region, type `C-c % C-r', and enter the desired major mode. *Note Interactive::, for more details. A better way to add submode regions is by using submode classes, which store a lot of useful information for MMM Mode about how to add and manipulate the regions created. *Note Submode Classes::, for more details. There are several sample submode classes that come with MMM Mode, which are documented later in this manual. Look through these and determine if one of them fits your needs. If so, I suggest reading the comments on that mode. Then come back here to find out to use it. To apply a submode class to a buffer interactively, turn MMM Mode on as above, then type `C-c % C-c' and enter the name of the class. Submode regions should be added automatically, if there are any regions in the buffer appropriate to the submode class. If you want a given file to always use a given submode class, you can express this in a file variable: add a line containing the string `-*- mmm-classes: CLASS -*-' at the top of the file. *Note File Variables: (emacs)File Variables, for more information and other methods. Now whenever MMM Mode is turned on in that file, it will be mmm-ified according to CLASS. If `mmm-global-mode' is non-nil, then MMM Mode will turn itself on whenever a file with a `mmm-classes' local variable is opened. *Note Global Mode::, for more information. If you want a submode class to apply to _all_ files in a certain major mode or with a certain extension, add a line such as this to your initialization file: (mmm-add-mode-ext-class MODE EXTENSION CLASS) After this call, any file opened whose name matches the regular expression EXTENSION _and_ whose default mode is MODE will be automatically mmm-ified according to CLASS (assuming `mmm-global-mode' is non-nil). If one of EXTENSION or MODE is `nil', a file need only satisfy the other one to be mmm-ified. You can now read the rest of this manual to learn more about how MMM Mode works and how to configure it to your preferences. If none of the supplied submode classes fit your needs, then you can try to write your own. *Note Writing Classes::, for more information.  File: mmm.info, Node: Basics, Next: Customizing, Prev: Overview, Up: Top 2 MMM Mode Basics ***************** This chapter explains the most important parts of how to use MMM Mode. * Menu: * MMM Minor Mode:: The Emacs minor mode that manages it all. * Submode Classes:: What they are and how to use them. * Selecting Classes:: How MMM Mode knows what classes to use. * Insertion:: Inserting new submode regions automatically. * Re-parsing:: Re-scanning for submode regions. * Interactive:: Adding submode regions manually. * Global Mode:: Turning MMM Mode on automatically.  File: mmm.info, Node: MMM Minor Mode, Next: Submode Classes, Prev: Basics, Up: Basics 2.1 The MMM Minor Mode ====================== An Emacs minor mode is an optional feature which can be turned on or off in a given buffer, independently of the major mode. *Note Minor Modes: (emacs)Minor Modes. MMM Mode is implemented as a minor mode which manages the submode regions. This minor mode must be turned on in a buffer for submode regions to be effective. When activated, the MMM Minor mode is denoted by `MMM' in the mode line (*note Mode Line::). * Menu: * Enabling MMM Mode:: Turning MMM Mode on and off. * MMM Mode Keys:: Default key bindings in MMM Mode.  File: mmm.info, Node: Enabling MMM Mode, Next: MMM Mode Keys, Prev: MMM Minor Mode, Up: MMM Minor Mode 2.1.1 Enabling MMM Mode ----------------------- If `mmm-global-mode' is non-`nil' (*note Global Mode::), then the MMM minor mode will be turned on automatically whenever a file with associated submode classes is opened (*note Selecting Classes::). It is also turned on by interactive mmm-ification (*note Interactive::), although the interactive commands do not have key bindings when it is not on and must be invoked via `M-x'. You can also turn it on (or off) manually with `M-x mmm-mode', in which case it applies all submode classes associated with the buffer. Turning MMM Mode off automatically removes all submode regions from the buffer. -- Command: mmm-mode ARG Toggle the state of MMM Mode in the current buffer. If ARG is supplied, turn MMM Mode on if and only if ARG is positive. -- Function: mmm-mode-on Turn MMM Mode on unconditionally in the current buffer. -- Function: mmm-mode-off Turn MMM Mode off unconditionally in the current buffer. -- Variable: mmm-mode This variable represents whether MMM Mode is on in the current buffer. Do not set this variable directly; use one of the above functions.  File: mmm.info, Node: MMM Mode Keys, Prev: Enabling MMM Mode, Up: MMM Minor Mode 2.1.2 Key Bindings in MMM Mode ------------------------------ When MMM Mode is on, it defines a number of key bindings. By default, these are bound after the prefix sequence `C-c %'. Minor mode keymaps are supposed to use `C-c PUNCTUATION' sequences, and I find this one to be a good mnemonic because `%' is used by Mason to denote special tags. This prefix key can be customized; *note Key Bindings::. There are two types of key bindings in MMM Mode: "commands" and "insertions". Command bindings run MMM Mode interactive functions to do things like re-parse the buffer or end the current submode region, and are defined statically as normal Emacs key-bindings. Insertion bindings insert submode region skeletons with delimiters into the buffer, and are defined dynamically, according to which submode classes (*note Submode Classes::) are in effect, via a keymap default binding. To distinguish between the two, MMM Mode uses distinct modifier keys for each. By default, command bindings use the control key (e.g. `C-c % C-b' re-parses the buffer), and insertion bindings do not (e.g. `C-c % p', when the Mason class is in effect, inserts a `<%perl>...' region). This makes the command bindings different from in previous versions, however, so the variable `mmm-use-old-bindings' is provided. If this variable is set to `t' before MMM Mode is loaded, the bindings will be reversed: insertion bindings will use the control key and command bindings will not. Normally, Emacs gives help on a prefix command if you type `C-h' after that command (e.g. `C-x C-h' displays all key bindings starting with `C-x'). Because of how insertion bindings are implemented dynamically with a default binding, they do not show up when you hit `C-c % C-h'. For this reason, MMM Mode defines the command `C-c % h' which displays a list of all currently valid insertion key sequences. If you use the defaults for command and insertion bindings, the `C-h' and `h' should be mnemonic. In the rest of this manual, I will assume you are using the defaults for the mode prefix (`C-c %') and the command and insertion modifiers. You can customize them, however; *note Key Bindings::.  File: mmm.info, Node: Submode Classes, Next: Selecting Classes, Prev: MMM Minor Mode, Up: Basics 2.2 Understanding Submode Classes ================================= A submode class represents a "type" of submode region. It specifies how to find the regions, what their delimiters look like, what submode they should be, how to insert them, and how they behave in other ways. It is represented by a symbol, such as `mason' or `eval-elisp'. For example, in the Mason set of classes, there is one class representing all `<%...%>' inline Perl regions, and one representing regions such as `<%perl>...', `<%init>...', and so on. These are different to Mason, but to Emacs they are all just Perl sections, so they are covered by the same submode class. But it would be tedious if whenever we wanted to use the Mason classes, we had to specify both of these. (Actually, this is a simplification: there are some half a dozen Mason submode classes.) So submode classes can also "group" others together, and we can refer to the `mason' class and mean all of them. The way a submode class is used is to "apply" it to a buffer. This scans the buffer for regions which should be submode regions according to that class, and also remembers the class for later, so that new submode regions can be inserted and scanned for later.  File: mmm.info, Node: Selecting Classes, Next: Insertion, Prev: Submode Classes, Up: Basics 2.3 How MMM Mode selects submode classes ======================================== Submode classes that apply to a buffer come from three sources: mode/extension-associated classes, file-local classes, and interactive MMM-ification (*note Interactive::). Whenever MMM Mode is turned on in a buffer (*note MMM Minor Mode::, and *note Global Mode::), it inspects the value of two variables to determine which classes to automatically apply to the buffer. This covers the first two sources; the latter is covered in a later chapter. * Menu: * File Classes:: Classes for a single file. * Mode-Ext Classes:: Classes for a given mode or extension. * Global Classes:: Classes for all MMM Mode buffers.  File: mmm.info, Node: File Classes, Next: Mode-Ext Classes, Prev: Selecting Classes, Up: Selecting Classes 2.3.1 File-Local Submode Classes -------------------------------- -- Variable: mmm-classes This variable is always buffer-local when set. Its value should be either a single symbol or a list of symbols. Each symbol represents a submode class that is applied to the buffer. `mmm-classes' is usually set in a file local variables list. *Note File Variables: (emacs)File Variables. The easiest way to do this is for the first line of the file to contain the string `-*- mmm-classes: CLASSES -*-', where CLASSES is the desired value of `mmm-classes' for the file in question. It can also be done with a local variables list at the end of the file.  File: mmm.info, Node: Mode-Ext Classes, Next: Global Classes, Prev: File Classes, Up: Selecting Classes 2.3.2 Submode Classes Associated with Modes and Extensions ---------------------------------------------------------- -- User Option: mmm-mode-ext-classes-alist This global variable associates certain submode classes with major modes and/or file extensions. Its value is a list of elements of the form `(MODE EXT CLASS)'. Any buffer whose major mode is MODE (a symbol) _and_ whose file name matches EXT (a regular expression) will automatically have the submode class CLASS applied to it. If MODE is `nil', then only EXT is considered to determine if a buffer fits the criteria, and vice versa. Thus if both MODE and EXT are nil, then CLASS is applied to _all_ buffers in which MMM Mode is on. Note that EXT can be any regular expression, although its name indicates that it most often refers to the file extension. If CLASS is the symbol `t', then no submode class is actually applied for this association. However, if `mmm-global-mode' is non-`nil' and non-`t', MMM Mode will be turned on in matching buffers even if there are no actual submode classes being applied. *Note Global Mode::. -- Function: mmm-add-mode-ext-class MODE EXT CLASS This function adds an element to `mmm-mode-ext-classes-alist', associating the submode class CLASS with the major mode MODE and extension EXT. Older versions of MMM Mode required this function to be used to control the value of `mmm-mode-ext-classes-alist', rather than setting it directly. In this version it is provided purely for convenience and backward compatibility.  File: mmm.info, Node: Global Classes, Prev: Mode-Ext Classes, Up: Selecting Classes 2.3.3 Globally Applied Classes and the Universal Class ------------------------------------------------------ In addition to file-local and mode-ext-associated submode classes, MMM Mode also allows you to specify that certain submode classes apply to _all_ buffers in which MMM Mode is enabled. -- User Option: mmm-global-classes This variable's value should be a list of submode classes that apply to all buffers with MMM Mode on. It can be overriden in a file local variables list, such as to disable global class for a specific file. Its default value is `(universal)'. The default global class is the "universal class", which is defined in the file `mmm-univ.el' (loaded automatically), and allows the author of text to specify that a certain section of it be in a specific major mode. Thus, for example, when writing an email message that includes sample code, the author can allow readers of the message (who use emacs and MMM) to view the code in the appropriate major mode. The syntax used is `{%MODE%} ... {%/MODE%}', where MODE should be the name of the major mode, with or without the customary `-mode' suffix: for example, both `cperl' and `cperl-mode' are acceptable. The universal class also defines an insertion key, `/', which prompts for the submode to use. *Note Insertion::. The universal class is most useful when `mmm-global-mode' is set to `t'; *note Global Mode::.  File: mmm.info, Node: Insertion, Next: Re-parsing, Prev: Selecting Classes, Up: Basics 2.4 Inserting new submode regions ================================= So much for noticing submode regions already present when you open a file. When editing a file with MMM Mode on, you will often want to add a new submode region. MMM Mode provides several facilities to help you. The simplest is to just hit a few keys and have the region and its delimiters inserted for you. Each submode class can define an association of keystrokes with "skeletons" to insert a submode region. If there are several submode classes enabled in a buffer, it is conceivable that the keys they use for insertion might conflict, but unlikely as most buffers will not use more than one or two submode classes groups. As an example of how insertion works, consider the Mason classes. In a buffer with MMM Mode enabled and Mason associated, the key sequence `C-c % p' inserts the following perl section (the semicolon is to prevent CPerl Mode from getting confused--*note Mason::): <%perl>-<-; -!- ->- In this schematic representation, the string `-!-' represents the position of point (the cursor), `-<-' represents the beginning of the submode region, and `->-' its end. All insertion keys come after the MMM Mode prefix keys (by default `C-c %'; *note Key Bindings::) and are by default single characters such as `p', `%', and `i'. To avoid confusion, all the MMM Mode commands are bound by default to control characters (after the same prefix keys), such as `C-b', `C-%' and `C-r'. This is a change from earlier versions of MMM Mode, and can be customized; see *note Key Bindings::. To find out what insertion keys are available, consult the documentation for the submode class you are using. If it is one of the classes supplied with MMM Mode, you can find it in this Info file. Because insertion keys are implemented with a "default binding" for flexibility, they do not show up in the output of `C-h m' and cannot be found with `C-h k'. For this reason, MMM Mode supplies the command `C-c % h' (`mmm-insertion-help' to view the available insertion keys.  File: mmm.info, Node: Re-parsing, Next: Interactive, Prev: Insertion, Up: Basics 2.5 Re-Parsing Submode Regions ============================== Describe `mmm-parse-buffer', `mmm-parse-region', `mmm-parse-block', and `mmm-clear-current-region'.  File: mmm.info, Node: Interactive, Next: Global Mode, Prev: Re-parsing, Up: Basics 2.6 Interactive MMM-ification Functions ======================================= There are several commands you can use to create submode regions interactively, rather than by applying a submode class to a buffer. These commands (in particular, `mmm-ify-region'), can be useful when editing a file or email message containing a snippet of code in some other language. Also see *note Global Classes::, for an alternate approach to the same problem. `C-c % C-r' Creates a submode region between point and mark. Prompts for the submode to use, which must be a valid Emacs major mode name, such as `emacs-lisp-mode' or `cperl-mode'. Adds markers to the interactive history. (`mmm-ify-region') `C-c % C-c' Applies an already-defined submode class to the buffer, which it prompts for. Adds this class to the interactive history. (`mmm-ify-by-class') `C-c % C-x' Scans the buffer for submode regions (prompts for the submode) using front and back regular expressions that it also prompts for. Briefly, it starts at the beginning of the buffer and searches for the front regexp. If it finds a match, it searches for the back regexp. If it finds a match for that as well, it makes a submode region between the two matches and continues searching until no more matches are found. Adds the regexps to the interactive history. (`mmm-ify-by-regexp') These commands are also useful when designing a new submode class (*note Submode Classes::). Working with the regexps interactively can make it easier to debug and tune the class before starting to use it on automatic. All these commands also add to value of the following variable. -- Variable: mmm-interactive-history Stores a history of all interactive mmm-ification that has been performed in the current buffer. This way, for example, the re-parsing functions (*note Re-parsing::) will respect interactively added regions, and the insertion keys for classes that were added interactively are available. If for any reason you want to "wipe the slate clean", this command should help you. By default, it has no key binding, so you must invoke it with `M-x mmm-clear-history '. -- Command: mmm-clear-history Clears all history of interactive mmm-ification in the current buffer. This command does not affect existing submode regions; to remove them, you may want to re-parse the buffer with `C-c % C-b' (`mmm-parse-buffer').  File: mmm.info, Node: Global Mode, Prev: Interactive, Up: Basics 2.7 MMM Global Mode =================== When a file has associated submode classes (*note Selecting Classes::), you may want MMM Mode to turn itself on and parse that file for submode regions automatically whenever it is opened in an Emacs buffer. The value of the following variable controls when MMM Mode turns itself on automatically. -- User Option: mmm-global-mode Do not be misled by the fact that this variable's name ends in `-mode': it is not a simple on/off switch. There are three possible (meanings of) values for it: `t', `nil', and anything else. When this variable is `nil', MMM Mode is never enabled automatically. If it is enabled manually, such as by typing `M-x mmm-mode', any submode classes associated with the buffer will still be used, however. When this variable is `t', MMM Mode is enabled automatically in _all_ buffers, including those not visiting files, except those whose major mode is an element of `mmm-never-modes'. The default value of this variable contains modes such as `help-mode' and `dired-mode' in which most users would never want MMM Mode, and in which MMM might cause problems. When this variable is neither `nil' nor `t', MMM Mode is enabled automatically in all buffers that would have associated submode classes; i.e. only if there would be something for it to do. The value of `mmm-never-modes' is still respected, however. Note that this can include buffers not visiting files, if that buffer's major mode is present in `mmm-mode-ext-classes-alist' with a `nil' value for EXT (*note Mode-Ext Classes::). Submode class values of `t' in `mmm-mode-ext-classes-alist' cause MMM Mode to be enabled in matching buffers, but supply no submode classes to be applied. * Menu: * Major Mode Hook:: Using MMM's Major Mode Hook  File: mmm.info, Node: Major Mode Hook, Prev: Global Mode, Up: Global Mode 2.7.1 The Major Mode Hook ------------------------- This section is intended for users who understand Emacs Lisp and want to know how MMM Global Mode is implemented, and perhaps use the same technique. In fact, MMM Mode exports a hook variable that you can use easily, without understanding any of the details--see below. In order to enable itself in _all_ buffers, however, MMM Mode has to hook itself into all major modes. Global Font Lock Mode from the standard Emacs distribution (*note Font Lock: (emacs)Font Lock.) has a similar problem, and solves it by adding a function to `change-major-mode-hook', which is run by `kill-all-local-variables', which is run in turn by all major mode functions at the _beginning_. This function stores a list of which buffers need fontification. It then adds a different function to `post-command-hook', which checks if the current buffer needs fontification, and if so performs it. MMM Global Mode uses the same technique. In the interests of generality, and for your use, the function that MMM Mode runs in `post-command-hook' (`mmm-run-major-mode-hook') is not specific to MMM Mode, but rather runs the hook variable `mmm-major-mode-hook', which by default contains a function (`mmm-mode-on-maybe') which possibly turns MMM Mode on, depending on the value of `mmm-global-mode'. Thus, to run another function in all major modes, all you need to do is add it to this hook. For example, the following line in an initialization file will turn on Auto Fill Mode (*note Auto Fill: (emacs)Auto Fill.) in all buffers: (add-hook 'mmm-major-mode-hook 'turn-on-auto-fill)  File: mmm.info, Node: Customizing, Next: Supplied Classes, Prev: Basics, Up: Top 3 Customizing MMM Mode ********************** This chapter explains how to customize the appearance and functioning of MMM Mode however you want. * Menu: * Region Coloring:: Changing or removing background colors. * Preferred Modes:: Choosing which major modes to use. * Mode Line:: What is displayed in the mode line. * Key Bindings:: Customizing the MMM Mode key bindings. * Local Variables:: What local variables are saved for submodes. * Changing Classes:: Changing the supplied submode classes. * Hooks:: How to make MMM Mode run your code.  File: mmm.info, Node: Region Coloring, Next: Preferred Modes, Prev: Customizing, Up: Customizing 3.1 Customizing Region Coloring =============================== By default, MMM Mode highlights all submode regions with a background color. There are three levels of this decoration, controlled by the following variable: -- User Option: mmm-submode-decoration-level This variable controls the level of coloring of submode regions. It should be one of the integers 0, 1, or 2, representing (respectively) none, low, and high coloring. No coloring means exactly that. Submode regions have the same background as the rest of the text. This produces the minimal interference with font-lock coloration. In particular, if you want to use background colors for font-lock, this may be a good idea, because the submode highlight, if present, overrides any font-lock background coloring. Low coloring uses the same background color for all submode regions. This color is specified with the face `mmm-default-submode-face' (*note Faces: (emacs)Faces.) which can be customized, either through the Emacs "customize" interface or using direct Lisp commands such as `set-face-background'. Of course, other aspects of the face can also be set, such as the foreground color, bold, underline, etc. These are more likely to conflict with font-lock, however, so only a background color is recommended. High coloring uses multiple background colors, depending on the function of the submode region. The recognized functions and their meanings are as follows: `init' Code that is executed at the beginning of (something), as initialization of some sort. `cleanup' Code that is executed at the end of (something), as some sort of clean up facility. `declaration' Code that provides declarations of some sort, perhaps global or local arguments, variables, or methods. `comment' Text that is not executed as code, but instead serves to document the code around it. Submode regions of this function often use a mode such as Text Mode rather than a programming language mode. `output' An expression that is evaluated and its value interpolated into the output produced. `code' Executed code not falling under any other category. `special' Submode regions not falling under any other category, such as component calls. The different background colors are provided by the faces `mmm-FUNCTION-submode-face', which can be customized in the same way as `mmm-default-submode-face'.  File: mmm.info, Node: Preferred Modes, Next: Mode Line, Prev: Region Coloring, Up: Customizing 3.2 Preferred Major Modes ========================= Certain of the supplied submode classes know only the language that certain sections are written in, but not what major mode you prefer to use to edit such code. For example, many people prefer CPerl mode over Perl mode; you may have a special mode for Javascript or just use C++ mode. This variable allows you to tell submodes such as Mason (*note Mason::) and Embedded Javascript (*note Javascript::) what major mode to use for the submodes: -- User Option: mmm-major-mode-preferences The elements of this list are cons cells of the form `(LANGUAGE . MODE)'. LANGUAGE should be a symbol such as `perl', `html-js', or `java', while MODE should be the name of a major mode such as `perl-mode', `cperl-mode', `javascript-mode', or `c++-mode'. You probably won't have to set this variable at all; MMM tries to make intelligent guesses about what modes you prefer. For example, if a function called `javascript-mode' exists, it is chosen, otherwise `c++-mode' is used. Similarly for `jde-mode' and `java-mode'. If you do need to change the defaults, you may find the following function convenient. -- Function: mmm-set-major-mode-preferences LANGUAGE MODE &optional DEFAULT Set the preferred major mode for LANGUAGE to MODE. If there is already a mode specified for LANGUAGE, and DEFAULT is nil or unsupplied, then it is changed. If DEFAULT is non-nil, then any existing mode is unchanged. This is used by packages to ensure that some mode is present, but not override any user-specified mode. If you are not writing a submode class, you should ignore the third argument. Thus, for example, to use `my-java-mode' for Java code, you would use the following line: (mmm-set-major-mode-preferences 'java 'my-java-mode)  File: mmm.info, Node: Mode Line, Next: Key Bindings, Prev: Preferred Modes, Up: Customizing 3.3 Customizing the Mode Line Display ===================================== By default, when in a submode region, MMM Mode changes the section of the mode line (*note Mode Line: (emacs)Mode Line.) that normally displays the major mode name--for example, `HTML'--to instead show both the dominant major mode and the currently active submode--for example, `HTML[CPerl]'. You can change this format, however. -- User Option: mmm-submode-mode-line-format The value of this variable should be a string containing one or both of the escape sequences `~M' and `~m'. The string displayed in the major mode section of the mode line when in a submode is obtained by replacing all occurrences of `~M' with the dominant major mode name and `~m' with the currently active submode name. For example, to display only the currently active submode, set this variable to `~m'. The default value is `~M[~m]'. The MMM minor mode also normally displays the string `MMM' in the minor mode section of the mode line to indicate when it is active. You can customize or disable this as well. -- User Option: mmm-mode-string This string is displayed in the minor mode section of the mode line when the MMM minor mode is active. If nonempty, it should begin with a space to separate the MMM indicator from that of other minor modes. To eliminate the indicator entirely, set this variable to the empty string.  File: mmm.info, Node: Key Bindings, Next: Local Variables, Prev: Mode Line, Up: Customizing 3.4 Customizing the MMM Mode Key Bindings ========================================= The default MMM Mode key bindings are explained in *note MMM Mode Keys::, and in *note Insertion::. There are a couple of ways to customize these bindings. -- User Option: mmm-mode-prefix-key The value of this variable (default is `C-c %') should be a key sequence to use as the prefix for the MMM Mode keymap. Minor modes typically use `C-c' followed by a punctuation character, but you can change it to any user-available key sequence. To have an effect, this variable should be set before MMM Mode is loaded. -- User Option: mmm-use-old-command-keys When this variable is `nil', MMM Mode commands use the control modifier and insertion keys no modifier. Any other value switches the two, so that `mmm-parse-buffer', for example, is bound to `C-c % b', while perl-section insertion in the Mason class is bound to `C-c % C-p'. This variable should be set before MMM Mode is loaded to have an effect. When MMM is loaded, it uses the value of `mmm-use-old-command-keys' to set the values of the variables `mmm-command-modifiers' and `mmm-insert-modifiers', so if you prefer you can set these variables instead. They should each be a list of key modifiers, such as `(control)' or `()'. The Meta modifier is used in some of the command and insertion keys, so it should not be used, and the Shift modifier is not particularly portable between Emacsen--if it works for you, feel free to use it. Other modifiers, such as Hyper and Super, are not universally available, but are valid when present.  File: mmm.info, Node: Local Variables, Next: Changing Classes, Prev: Key Bindings, Up: Customizing 3.5 Changing Saved Local Variables ================================== A lot of the functionality of MMM Mode--that which makes the major mode appear to change--is implemented by saving and restoring the values of local variables, or pseudo-variables. You can customize what variables are saved, and how, with the following variable. -- Variable: mmm-save-local-variables At its simplest, this is a list each of whose elements is a buffer-local variable whose value is saved and restored for each major mode. Each elements can also, however, be a list whose first element is the variable symbol and whose subsequent elements specify how and where the variable is to be saved. The second element of the list, if present, should be one of the symbols `global', `buffer', or `region'. If not present, the default value is `global'. The third element, if present, should be a list of major mode symbols in which to save the variable. In the list form, the variable symbol itself can be replaced with a cons cell of two functions, one to get the value and one to set the value. This is called a "pseudo-variable". Globally saved variables are the same in all (MMM-controlled) buffers and submode regions of each major mode listed in the third argument, or all major modes if it is `t' or not present. Buffer-saved variables are the same in all submode regions of a given major mode in each buffer, and region-saved variables can be different for each submode region. Pseudo-variables are used, for example, to save and restore the syntax table (*note Syntax: (emacs)Syntax.) and mode keymaps (*note Keymaps: (emacs)Keymaps.).  File: mmm.info, Node: Changing Classes, Next: Hooks, Prev: Local Variables, Up: Customizing 3.6 Changing the Supplied Submode Classes ========================================= If you need to use MMM with a syntax for which a submode class is not supplied, and you have some facility with Emacs Lisp, you can write your own; see *note Writing Classes::. However, sometimes you will only want to make a slight change to one of the supplied submode classes. You can do this, after that class is loaded, with the following functions. -- Function: mmm-set-class-parameter CLASS PARAM VALUE Set the value of the keyword parameter PARAM of the submode class CLASS to VALUE. *Note Writing Classes::, for an explanation of the meaning of each keyword parameter. This creates a new parameter if one is not already present in the class. -- Function: mmm-get-class-parameter CLASS PARAM Get the value of the keyword parameter PARAM for the submode class CLASS. Returns `nil' if there is no such parameter.  File: mmm.info, Node: Hooks, Prev: Changing Classes, Up: Customizing 3.7 Hooks Provided by MMM Mode ============================== MMM Mode defines several hook variables (*note Hooks: (emacs)Hooks.) which are run at different times. The most often used is `mmm-major-mode-hook' which is described in *note Major Mode Hook::, but there are a couple others. -- Variable: mmm-mode-hook This normal hook is run whenever MMM Mode is enabled in a buffer. -- Variable: mmm-MAJOR-MODE-hook This is actually a whole set of hook variables, a different one for every major mode. Whenever MMM Mode is enabled in a buffer, the corresponding hook variable for the dominant major mode is run. -- Variable: mmm-SUBMODE-submode-hook Again, this is a set of one hook variable per major mode. These hooks are run whenever a submode region of the corresponding major mode is created in any buffer, with point at the start of the new submode region. -- Variable: mmm-CLASS-class-hook This is a set of one hook variable per submode class. These hooks are run when a submode class is first applied to a given buffer. Submode classes also have a `:creation-hook' parameter which should be a function to run whenever a submode region is created with that class, with point at the beginning of the submode region. This can be set for supplied submode classes with `mmm-set-class-parameter'; *note Changing Classes::.  File: mmm.info, Node: Supplied Classes, Next: Writing Classes, Prev: Customizing, Up: Top 4 Supplied Submode Classes ************************** This chapter describes the submode classes that are supplied with MMM Mode. * Menu: * Mason:: Mason server-side Perl in HTML. * File Variables:: Elisp code in File Variables. * Here-documents:: Code in shell and Perl here-documents. * Javascript:: Javascript embedded in HTML. * Embedded CSS:: CSS Styles embedded in HTML. * Embperl:: Another syntax for Perl in HTML. * ePerl:: A general Perl-embedding syntax. * JSP:: Java code embedded in HTML. * RPM:: Shell scripts in RPM Spec Files. * Noweb:: Noweb literate programs.  File: mmm.info, Node: Mason, Next: File Variables, Prev: Supplied Classes, Up: Supplied Classes 4.1 Mason: Perl in HTML ======================= Mason is a syntax to embed Perl code in HTML and other documents. See `http://www.masonhq.com' for more information. The submode class for Mason components is called `mason' and is loaded on demand from `mmm-mason.el'. The current Mason class is intended to correctly recognize all syntax valid in Mason 0.896. There are insertion keys for most of the available syntax; use `mmm-insertion-help' (`C-c % h' by default) with Mason on to get a list. If you want to have mason submodes automatically in all Mason files, you can use automatic mode and filename associations; the details depend on what you call your Mason components and what major mode you use. *Note Mode-Ext Classes::. If you use an extension for your Mason files that emacs does not automatically place in your preferred HTML Mode, you will probably want to associate that extension with your HTML Mode as well; *note Choosing Modes: (emacs)Choosing Modes. This also goes for "special" Mason files such as autohandlers and dhandlers. The Perl mode used is controlled by the user: *Note Preferred Modes::. The default is to use CPerl mode, if present. Unfortunately, there are also certain problems with CPerl mode in submode regions. (Not to say that the original perl-mode would do any better--it hasn't been much tried.) First of all, the first line of a Perl section is usually indented as if it were a continuation line. A fix for this is to start with a semicolon on the first line. The insertion key commands do this whenever the Mason syntax allows it. <%perl>; print $var; In addition, some users have reported that the CPerl indentation sometimes does not work. This problem has not yet been tracked down, however, and more data about when it happens would be helpful. Some people have reported problems using PSGML with Mason. Adding the following line to a `.emacs' file should suffice to turn PSGML off and cause emacs to use a simpler HTML mode: (autoload 'html-mode "sgml-mode" "HTML Mode" t) Earlier versions of PSGML may require instead the following fix: (delete '("\\.html$" . sgml-html-mode) auto-mode-alist) (delete '("\\.shtml$" . sgml-html-mode) auto-mode-alist) Other users report using PSGML with Mason and MMM Mode without difficulty. If you don't have problems and want to use PSGML, you may need to replace `html-mode' in the suggested code with `sgml-html-mode'. (Depending on your version of PSGML, this may not be necessary.) Similarly, if you are using XEmacs and want to use the alternate HTML mode `hm--html-mode', replace `html-mode' with that symbol. One problem that crops up when using PSGML with Mason is that even ignoring the special tags and Perl code (which, as I've said, haven't caused me any problems), Mason components often are not a complete SGML document. For instance, my autohandlers often say <% $m->call_next %> in which case the actual components contain no doctype declaration, `', `', or `', confusing PSGML. One solution I've found is to use the variable `sgml-parent-document' in such incomplete components; try, for example, these lines at the end of a component. %# Local Variables: %# sgml-parent-document: ("autohandler" "body" nil ("body")) %# sgml-doctype: "/top/level/autohandler" %# End: This tells PSGML that the current file is a sub-document of the file `autohandler' and is included inside a `' tag, thus alleviating its confusion.  File: mmm.info, Node: File Variables, Next: Here-documents, Prev: Mason, Up: Supplied Classes 4.2 Elisp in a Local Variables List =================================== Emacs allows the author of a file to specify major and minor modes to be used while editing that file, as well as specifying values for other local Elisp variables, with a File Variables list. *Note File Variables: (emacs)File Variables. Since file variables values are Elisp objects (and with the `eval' special "variable", they are forms to be evaluated), one might want to edit them in `emacs-lisp-mode'. The submode class `file-variables' allows this, and is suitable for turning on in a given file with `mmm-classes', or in all files with `mmm-global-classes'.  File: mmm.info, Node: Here-documents, Next: Javascript, Prev: File Variables, Up: Supplied Classes 4.3 Here-documents ================== One of the long-time standard syntaxes for outputting large amounts of code (or text, or HTML, or whatever) from a script (notably shell scripts and Perl scripts) is the here-document syntax: print < Test Page END_HTML The `here-doc' submode class recognizes this syntax, and can even guess the correct submode to use in many cases. For instance, it would put the above example in `html-mode', noticing the string `HTML' in the name of the here-document. If you use less than evocative here-document names, or if the submode is recognized incorrectly for any other reason, you can tell it explicitly what submode to use. -- User Option: mmm-here-doc-mode-alist The value of this variable should be an alist, each element a cons pair associating a regular expression to a submode symbol. Whenever a here-document name matches one of these regexps, the corresponding submode is applied. For example, if this variable contains the element `("CODE" . cc-mode)', then any here-document whose name contains the string `CODE' will be put in `cc-mode'. The value of this variable overrides any guessing that the `here-doc' submode class would do otherwise.  File: mmm.info, Node: Javascript, Next: Embedded CSS, Prev: Here-documents, Up: Supplied Classes 4.4 Javascript in HTML ====================== The submode class `html-js' allows for embedding Javascript code in HTML documents. It recognizes both this syntax: and this syntax: The mode used for Javascript regions is controlled by the user; *Note Preferred Modes::.  File: mmm.info, Node: Embedded CSS, Next: Embperl, Prev: Javascript, Up: Supplied Classes 4.5 CSS embedded in HTML ======================== CSS (Cascading Style Sheets) can also be embedded in HTML. The `embedded-css' submode class recognizes this syntax: It uses `css-mode' if present, `c++-mode' otherwise. This can be customized: *Note Preferred Modes::.  File: mmm.info, Node: Embperl, Next: ePerl, Prev: Embedded CSS, Up: Supplied Classes 4.6 Embperl: More Perl in HTML ============================== Embperl is another syntax for embedding Perl in HTML. See `http://perl.apache.org/embperl' for more information. The `embperl' submode class recognizes most if not all of the Embperl embedding syntax. Its Perl mode is also controllable by the user; *Note Preferred Modes::.  File: mmm.info, Node: ePerl, Next: JSP, Prev: Embperl, Up: Supplied Classes 4.7 ePerl: General Perl Embedding ================================= Yet another syntax for embedding Perl is called ePerl. See `http://www.engelschall.com/sw/eperl/' for more information. The `eperl' submode class handles this syntax, using the Perl mode specified by the user; *Note Preferred Modes::.  File: mmm.info, Node: JSP, Next: RPM, Prev: ePerl, Up: Supplied Classes 4.8 JSP: Java Embedded in HTML ============================== JSP (Java Server Pages) is a syntax for embedding Java code in HTML. The submode class `jsp' handles this syntax, using a Java mode specified by the user; *Note Preferred Modes::. The default is `jde-mode' if present, otherwise `java-mode'.  File: mmm.info, Node: RPM, Next: Noweb, Prev: JSP, Up: Supplied Classes 4.9 RPM Spec Files ================== `mmm-rpm.el' contains the definition of an MMM Mode submode class for editing shell script sections within RPM (Redhat Package Manager) spec files. It is recommended for use in combination with `rpm-spec-mode.el' by Stig Bjørlykke and Steve Sanbeg (`http://www.xemacs.org/~stigb/rpm-spec-mode.el'). Suggested setup code: (add-to-list 'mmm-mode-ext-classes-alist '(rpm-spec-mode "\\.spec\\'" rpm-sh)) Thanks to Marcus Harnisch for contributing this submode class.  File: mmm.info, Node: Noweb, Prev: RPM, Up: Supplied Classes 4.10 Noweb literate programming =============================== `mmm-noweb.el' contains the definition of an MMM Mode submode class for editing Noweb documents. Most Noweb documents use \LaTeX for the documentation chunks. Code chunks in Noweb are document-specific, and the mode may be set with a local variable setting in the document. The variable MMM-NOWEB-CODE-MODE controls the global code chunk mode. Since Noweb files may have many languages in their code chunks, this mode also allows setting the mode by specifying a mode in the first line or two of a code chunk, using the normal Emacs first-line mode setting syntax. Note that this first-line mode setting only matches a single word for the mode name, and does not support the variable name setting of the generalized first file line syntax. % -*- mode: latex; mmm-noweb-code-mode: c++; -*- % First chunk delimiter! @ \noweboptions{smallcode} \title{Sample Noweb File} \author{Joe Kelsey\\ \nwanchorto{mailto:bozo@bozo.bozo}{\tt bozo@bozo.bozo}} \maketitle @ \section{Introduction} Normal noweb documentation for the required [[*]] chunk. <<*>>= // C++ mode here! // We might list the program here, or simply included chunks. <> @ %def myfile.cc @ \section{[[myfile.cc]]} This is [[myfile.cc]]. MMM noweb-mode understands code quotes in documentation. <>= // This section is indented separately from previous. @ @ \section{A Perl Chunk} We need a Perl chunk. <>= #!/usr/bin/perl # -*- perl -*- # Each differently named chunk is flowed separately. @ \section{Finish [[myfile.cc]]} When we resume a previously defined chunk, they are indented together. <>= // Pick up where we left off... @ The quoted code chunks inside documentation chunks are given the mode found in the variable MMM-NOWEB-QUOTE-MODE, if set, or the value in MMM-NOWEB-CODE-MODE otherwise. Also, each quoted chunk is set to have a unique name to prevent them from being indented as a unit. Suggested setup code: (mmm-add-mode-ext-class 'latex-mode "\\.nw\\'" 'noweb) (add-to-list 'auto-mode-alist '("\\.nw\\'" . latex-mode)) In mmm-noweb buffers, each differently-named code chunk has a different `:name', allowing all chunks with the same name to get indented together. This mode also supplies special paragraph filling operations for use in documentation areas of the buffer. From a primary-mode (`latex-mode, , emacs') region, pressing `C-c % C-q' will mark all submode regions with word syntax (`mmm-word-other-regions'), fill the current paragraph (`(fill-paragraph justify)'), and remove the syntax markings (`mmm-undo-syntax-other-regions'). Thanks to Joe Kelsey for contributing this class.  File: mmm.info, Node: Writing Classes, Next: Indices, Prev: Supplied Classes, Up: Top 5 Writing Submode Classes ************************* Sometimes (perhaps often) you may want to use MMM with a syntax for which it is suited, but for which no submode is supplied. In such cases you may have to write your own submode class. This chapter briefly describes how to write a submode class, from the basic to the advanced, with examples. * Menu: * Basic Classes:: Writing a simple submode class. * Paired Delimiters:: Matching paired delimiters. * Region Placement:: Placing the region more accurately. * Submode Groups:: Grouping several classes together. * Calculated Submodes:: Deciding the submode at run-time. * Calculated Faces:: Deciding the display face at run-time. * Insertion Commands:: Inserting regions automatically. * Region Names:: Naming regions for syntax grouping. * Other Hooks:: Running code at arbitrary points. * Delimiters:: Controlling delimiter overlays. * Misc Keywords:: Other miscellaneous options.  File: mmm.info, Node: Basic Classes, Next: Paired Delimiters, Prev: Writing Classes, Up: Writing Classes 5.1 Writing Basic Submode Classes ================================= Writing a submode class can become rather complex, if the syntax to match is complicated and you want to take advantage of some of MMM Mode's extra features. But a simple submode class is not particularly difficult to write. This section describes the basics of writing submode classes. Submode classes are stored in the variable `mmm-classes-alist'. Each element of this list represents a single submode class. For convenience, the function `mmm-add-classes' takes a list of submode classes and adds them all to this alist. Each class is represented by a list containing the class name--a symbol such as `mason' or `html-js'--followed by pairs of keywords and arguments called a "class specifier". For example, consider the specifier for the submode class `embedded-css': (mmm-add-classes '((embedded-css :submode css :face mmm-declaration-submode-face :front "]*>" :back ""))) The name of the submode is `embedded-css', the first element of the list. The rest of the list consists of pairs of keywords (symbols beginning with a colon) such as `:submode' and `:front', and arguments, such as `css' and `"]*>"'. It is the keywords and arguments that specify how the submode works. The order of keywords is not important; all that matters is the arguments that follow them. The three most important keywords are `:submode', `:front', and `:back'. The argument following `:submode' names the major mode to use in submode regions. It can be either a symbol naming a major mode, such as `text-mode' or `c++-mode', or a symbol to look up in `mmm-major-mode-preferences' (*note Preferred Modes::) such as `css', as in this case. The arguments following `:front' and `:back' are regular expressions (*note Regexps: (emacs)Regexps.) that should match the delimiter strings which begin and end the submode regions. In our example, CSS regions begin with a `' tag. The argument following `:face' specifies the face (background color) to use when `mmm-submode-decoration-level' is 2 (high coloring). *Note Region Coloring::, for a list of canonical available faces. There are many more possible keywords arguments. In the following sections, we will examine each of them and their uses in writing submode classes.  File: mmm.info, Node: Paired Delimiters, Next: Region Placement, Prev: Basic Classes, Up: Writing Classes 5.2 Matching Paired Delimiters ============================== A simple pair of regular expressions does not always suffice to exactly specify the beginning and end of submode regions correctly. For this reason, there are several other possible keyword/argument pairs which influence the matching process. Many submode regions are marked by paired delimiters. For example, the tags used by Mason (*note Mason::) include `<%init>...' and `<%args>...'. It would be possible to write a separate submode class for each type of region, but there is an easier way: the keyword argument `:save-matches'. If supplied and non-nil, it causes the regular expression `:back', before being searched for, to be formatted by replacing all strings of the form `~N' (where N is an integer) with the corresponding numbered subexpression of the match for `:front'. As an example, here is an excerpt from the `here-doc' submode class. *Note Here-documents::, for more information about this submode. :front "<<\\([a-zA-Z0-9_-]+\\)" :back "^~1$" :save-matches 1 The regular expression for `:front' matches `<<' followed by a string of one or more alphanumeric characters, underscores, and dashes. The latter string, which happens to be the name of the here-document, is saved as the first subexpression, since it is surrounded by `\(...\)'. Then, because the value of `:save-matches' is present and non-nil, the string `~1' is replaced in the value of `:back' by the name of the here-document, thus creating a regular expression to match the correct ending delimiter.  File: mmm.info, Node: Region Placement, Next: Submode Groups, Prev: Paired Delimiters, Up: Writing Classes 5.3 Placing Submode Regions Precisely ===================================== Normally, a submode region begins immediately after the end of the string matching the `:front' regular expression and ends immediately before the beginning of the string matching the `:back' regular expression. This can be changed with the keywords `:include-front' and `:include-back'. If their arguments are `nil', or they do not appear, the default behavior is unchanged. But if the argument of `:include-front' (respectively, `:include-back') is non-nil, the submode region will begin (respectively, end) immediately before (respectively, after) the string matching the `:front' (respectively, `:back') regular expression. In other words, these keywords specify whether or not the delimiter strings are _included_ in the submode region. When `:front' and `:back' are regexps, the delimiter is normally considered to be the entire matched region. This can be changed using the `:front-match' and `:back-match' keywords. The values of the keywords is a number specifying the submatch. This defaults to zero (specifying the whole regexp). Two more keywords which affect the placement of the region `:front-offset' and `:back-offset', which both take integers as arguments. The argument of `:front-offset' (respectively, `:back-offset') gives the distance in characters from the beginning (respectively, ending) location specified so far, to the actual point where the submode region begins (respectively, ends). For example, if `:include-front' is nil or unsupplied and `:front-offset' is 2, the submode region will begin two characters after the end of the match for `:front', and if `:include-back' is non-nil and `:back-offset' is -1, the region will end one character before the end of the match for `:back'. In addition to integers, the arguments of `:front-offset' and `:back-offset' can be functions which are invoked to move the point from the position specified by the matches and inclusions to the correct beginning or end of the submode region, or lists whose elements are either functions or numbers and whose effects are applied in sequence. To help disentangle these options, here is another excerpt from the `here-doc' submode class: :front "<<\\([a-zA-Z0-9_-]+\\)" :front-offset (end-of-line 1) :back "^~1$" :save-matches 1 Here the value of `:front-offset' is the list `(end-of-line 1)', meaning that from the end of the match for `:front', go to the end of the line, and then one more character forward (thus to the beginning of the next line), and begin the submode region there. This coincides with the normal behavior of here-documents: they begin on the following line and go until the ending flag. If the `:back' should not be able to start a new submode region, set the `:end-not-begin' keyword to non-nil.  File: mmm.info, Node: Submode Groups, Next: Calculated Submodes, Prev: Region Placement, Up: Writing Classes 5.4 Defining Groups of Submodes =============================== Sometimes more than one submode class is required to accurately reflect the behavior of a single type of syntax. For example, Mason has three very different types of Perl regions: blocks bounded by matched tags such as `<%perl>...', inline output expressions bounded by `<%...%>', and single lines of code which simply begin with a `%' character. In cases like these, it is possible to specify an "umbrella" class, to turn all these classes on or off together. -- Function: mmm-add-group GROUP CLASSES The submode classes CLASSES, which should be a list of lists, similar to what might be passed to `mmm-add-classes', are added just as by that function. Furthermore, another class named GROUP is added, which encompasses all the classes in CLASSES. Technically, an group class is specified with a `:classes' keyword argument, and the subsidiary classes are given a non-nil `:private' keyword argument to make them invisible. But in general, all you should ever need to know is how to invoke the function above. -- Function: mmm-add-to-group GROUP CLASSES Adds a list of classes to an already existing group. This can be used, for instance, to add a new quoting definition to HTML-JS using this example to add the quote characters "%=%": (mmm-add-to-group 'html-js '((js-html :submode javascript :face mmm-code-submode-face :front "%=%" :back "%=%" :end-not-begin t)))  File: mmm.info, Node: Calculated Submodes, Next: Calculated Faces, Prev: Submode Groups, Up: Writing Classes 5.5 Calculating the Correct Submode =================================== In most cases, the author of a submode class will know in advance what major mode to use, such as `text-mode' or `c++-mode'. If there are multiple possible modes that the user might desire, then `mmm-major-mode-preferences' should be used (*note Preferred Modes::). The function `mmm-set-major-mode-preferences' can be used, with a third argument, to ensure than the mode is present. In some cases, however, the author has no way of knowing in advance even what language the submode region will be in. The `here-doc' class is one of these. In such cases, instead of the `:submode' keyword, the `:match-submode' keyword must be used. Its argument should be a function, probably written by the author of the submode class, which calculates what major mode each region should use. It is invoked immediately after a match is found for `:front', and is passed one argument: a string representing the front delimiter. Normally this string is simply whatever was matched by `:front', but this can be changed with the keyword `:front-form' (*note Delimiters::). The function should then return a symbol that would be a valid argument to `:submode': either the name of a mode, or that of a language to look up a preferred mode. If it detects an invalid match--for example, the user has specified a mode which is not available--it should `(signal 'mmm-no-matching-submode nil)'. Since here-documents can contain code in any language, the `here-doc' submode class uses `:match-submode' rather than `:submode'. The function it uses is `mmm-here-doc-get-mode', defined in `mmm-sample.el', which inspects the name of the here-document for flags indicating the proper mode. For example, this code should probably be in `perl-mode' (or `cperl-mode'): print <' and `") (js-script :submode js-mode :face mmm-code-submode-face :front "]*>[ \t]*\n?" :back "[ \t]*" :insert ((?j js-tag nil @ "" @))))) ;;}}} ;;{{{ CSS in HTML (mmm-add-group 'html-css '((css-cdata :submode css-mode :face mmm-code-submode-face :front "]*>[ \t\n]*\\(//\\)?[ \t\n]*") (css :submode css-mode :face mmm-code-submode-face :front "]*>[ \t]*\n?" :back "[ \t]*" :insert ((?c css-tag nil @ "" @))))) ;;}}} ;;{{{ Here-documents ;; Here we match the here-document syntax used by Perl and shell ;; scripts. We try to be automagic about recognizing what mode the ;; here-document should be in. To make sure that it is recognized ;; correctly, the name of the mode, perhaps minus `-mode', in upper ;; case, and/or with hyphens converted to underscores, should be ;; separated from the rest of the here-document name by hyphens or ;; underscores. (defvar mmm-here-doc-mode-alist '() "Alist associating here-document name regexps to submodes. Normally, this variable is unnecessary, as the `here-doc' submode class tries to automagically recognize the right submode. If you use here-document names that it doesn't recognize, however, then you can add elements to this alist. Each element is \(REGEXP . MODE) where REGEXP is a regular expression matched against the here-document name and MODE is a major mode function symbol.") (defun mmm-here-doc-get-mode (string) (string-match "[a-zA-Z_-]+" string) (setq string (match-string 0 string)) (or (mmm-ensure-modename ;; First try the user override variable. (some #'(lambda (pair) (if (string-match (car pair) string) (cdr pair) nil)) mmm-here-doc-mode-alist)) (let ((words (split-string (downcase string) "[_-]+"))) (or (mmm-ensure-modename ;; Try the whole name, stopping at "mode" if present. (intern (mapconcat #'identity (nconc (ldiff words (member "mode" words)) (list "mode")) "-"))) ;; Try each word by itself (preference list) (some #'(lambda (word) (mmm-ensure-modename (intern word))) words) ;; Try each word with -mode tacked on (some #'(lambda (word) (mmm-ensure-modename (intern (concat word "-mode")))) words) ;; Try each pair of words with -mode tacked on (loop for (one two) on words if (mmm-ensure-modename (intern (concat one two "-mode"))) return it) ;; I'm unaware of any modes whose names, minus `-mode', ;; are more than two words long, and if the entire mode ;; name (perhaps minus `-mode') doesn't occur in the ;; here-document name, we can give up. (signal 'mmm-no-matching-submode nil))))) (mmm-add-classes '((here-doc :front "<<[\"\'\`]?\\([a-zA-Z0-9_-]+\\)" :front-offset (end-of-line 1) :back "^~1$" :save-matches 1 :delimiter-mode nil :match-submode mmm-here-doc-get-mode :insert ((?d here-doc "Here-document Name: " @ "<<" str _ "\n" @ "\n" @ str "\n" @)) ))) ;;}}} ;;{{{ Embperl (mmm-add-group 'embperl '((embperl-perl :submode perl :front "\\[\\([-\\+!\\*\\$]\\)" :back "~1\\]" :save-matches 1 :match-name "embperl" :match-face (("[+" . mmm-output-submode-face) ("[-" . mmm-code-submode-face) ("[!" . mmm-init-submode-face) ("[*" . mmm-code-submode-face) ("[$" . mmm-special-submode-face)) :insert ((?p embperl "Region Type (Character): " @ "[" str @ " " _ " " @ str "]" @) (?+ embperl+ ?p . "+") (?- embperl- ?p . "-") (?! embperl! ?p . "!") (?* embperl* ?p . "*") (?$ embperl$ ?p . "$") ) ) (embperl-comment :submode text-mode :face mmm-comment-submode-face :front "\\[#" :back "#\\]" :insert ((?# embperl-comment nil @ "[#" @ " " _ " " @ "#]" @)) ))) ;;}}} ;;{{{ ePerl (mmm-add-group 'eperl '((eperl-expr :submode perl :face mmm-output-submode-face :front "<:=" :back ":>" :insert ((?= eperl-expr nil @ "<:=" @ " " _ " " @ ":>" @))) (eperl-code :submode perl :face mmm-code-submode-face :front "<:" :back "_?:>" :match-name "eperl" :insert ((?p eperl-code nil @ "<:" @ " " _ " " @ ":>" @) (?: eperl-code ?p . nil) (?_ eperl-code_ nil @ "<:" @ " " _ " " @ "_:>" @))) (eperl-comment :submode text :face mmm-comment-submode-face :front ":>//" :back "\n") )) ;;}}} ;;{{{ File Variables ;; This submode class puts file local variable values, specified with ;; a `Local Variables:' line as in (emacs)File Variables, into Emacs ;; Lisp Mode. It is a good candidate to put in `mmm-global-classes'. (defun mmm-file-variables-verify () ;; It would be nice to cache this somehow, which could be done in a ;; buffer-local variable with markers for positions, but the trick ;; is knowing when to expire the cache. (let ((bounds (save-excursion (save-match-data (goto-char (point-max)) (backward-page) (and (re-search-forward "^\\(.*\\)Local Variables:" nil t) (list (match-string 1) (progn (end-of-line) (point)) (and (search-forward (format "%sEnd:" (match-string 1)) nil t) (progn (beginning-of-line) (point))))))))) (and bounds (caddr bounds) (save-match-data (string-match (format "^%s" (regexp-quote (car bounds))) (match-string 0))) (> (match-beginning 0) (cadr bounds)) (< (match-end 0) (caddr bounds))))) (defun mmm-file-variables-find-back (bound) (forward-sexp) (if (> (point) bound) nil (looking-at ""))) (mmm-add-classes '((file-variables :front ".+:" :front-verify mmm-file-variables-verify :back mmm-file-variables-find-back :submode emacs-lisp-mode :delimiter-mode nil ))) ;;}}} ;;{{{ JSP Pages (mmm-add-group 'jsp `((jsp-comment :submode text-mode :face mmm-comment-submode-face :front "<%--" :back "--%>" :insert ((?- jsp-comment nil @ "<%--" @ " " _ " " @ "--%>" @)) ) (jsp-code :submode java :match-face (("<%!" . mmm-declaration-submode-face) ("<%=" . mmm-output-submode-face) ("<%" . mmm-code-submode-face)) :front "<%[!=]?" :back "%>" :match-name "jsp" :insert ((?% jsp-code nil @ "<%" @ " " _ " " @ "%>" @) (?! jsp-declaration nil @ "<%!" @ " " _ " " @ "%>" @) (?= jsp-expression nil @ "<%=" @ " " _ " " @ "%>" @)) ) (jsp-directive :submode text-mode :face mmm-special-submode-face :front "<%@" :back "%>" :insert ((?@ jsp-directive nil @ "<%@" @ " " _ " " @ "%>" @)) ))) ;;}}} ;;{{{ SGML DTD ;; Thanks to Yann Dirson for writing and ;; contributing this submode class. (mmm-add-classes '((sgml-dtd :submode dtd-mode :face mmm-declaration-submode-face :delimiter-mode nil :front "[]*\\[" :back "]>"))) ;;}}} ;;{{{ PHP in HTML (mmm-add-group 'html-php '((html-php-output :submode php-mode :face mmm-output-submode-face :front "<\\?php *echo " :back "\\?>" :include-front t :front-offset 5 :insert ((?e php-echo nil @ "" @)) ) (html-php-code :submode php-mode :face mmm-code-submode-face :front "<\\?\\(php\\)?" :back "\\?>" :insert ((?p php-section nil @ "" @) (?b php-block nil @ "" @)) ))) ;;}}} ;; NOT YET UPDATED ;;{{{ HTML in PL/SQL;-COM- ;-COM- ;-COM-;; This one is the most complex example. In PL/SQL, HTML is generally ;-COM-;; output as a (single quote delimited) string inside a call to htp.p or ;-COM-;; its brethren. The problem is that there may be strings outside of ;-COM-;; htp.p calls that should not be HTML, so we need to only look inside ;-COM-;; these calls. The situation is complicated by PL/SQL's rule that two ;-COM-;; sequential single quotes in a string mean to put a single quote ;-COM-;; inside the string. ;-COM- ;-COM-;; These functions have not been thoroughly tested, and always search ;-COM-;; the entire buffer, ignoring START and END. ;-COM- ;-COM-(defun mmm-html-in-plsql (start end) ;-COM- (save-match-data ;-COM- (let ((case-fold-search t)) ;-COM- (and (re-search-forward "htp.p\\(\\|rn\\|rint\\)1?(" nil t) ;-COM- (mmm-html-in-plsql-in-htp ;-COM- ;; Find the end of the procedure call ;-COM- (save-excursion (forward-char -1) (forward-sexp) (point)) ;-COM- start end))))) ;-COM- ;-COM-(defun mmm-html-in-plsql-in-htp (htp-end start end) ;-COM- (let (beg end) ;-COM- (or (and (re-search-forward "'" htp-end 'limit) ;-COM- (setf beg (match-end 0)) ;-COM- ;; Find an odd number of 's to end the string. ;-COM- (do ((lgth 0 (length (match-string 0)))) ;-COM- ((oddp lgth) t) ;-COM- (re-search-forward "'+" nil t)) ;-COM- (setf end (1- (match-end 0))) ;-COM- (cons (cons beg end) ;-COM- (mmm-html-in-plsql-in-htp htp-end start end))) ;-COM- ;; No more strings in the procedure call; look for another. ;-COM- (and (eql (point) htp-end) ;-COM- (mmm-html-in-plsql start end))))) ;-COM- ;-COM-(add-to-list 'mmm-classes-alist ;-COM- '(htp-p (:function html-mode mmm-html-in-plsql))) ;-COM- ;;}}} (provide 'mmm-sample) ;;; mmm-sample.el ends here mmm-mode-0.5.1/NEWS0000664000175000017500000002407412114106645010656 00000000000000MMM Mode NEWS -- history of user-visible changes. -*-outline-*- Copyright (C) 2003, 2004 Michael Abraham Shulman Copyright (C) 2013 Dmitry Gutov See the file COPYING for copying conditions. Please submit bug reports at https://github.com/purcell/mmm-mode/issues * Changes in MMM Mode 0.5.1 Some minor documentation updates and bugfixes. * Changes in MMM Mode 0.5.0 ** Compatibility with recent Emacsen Updated to work with Emacs 23 and 24. Removed some compatibility code for older versions. Added new local variables used in the latest js-mode and cc-engine modes. ** New submode classes New submode classes for ERB and EJS templates, both in mmm-erb.el. It also includes a smart indentation algorithm, supporting them together with script and style tag subregions in HTML code. ** Parsing when idle Setting `mmm-parse-when-idle' will make MMM Mode re-parse modified buffers when Emacs is idle. This can lead to visible pauses, though, depending on the size of the buffer and the number of subregions. ** Support submode-specific syntax functions Relevant for Emacs 24: we define a composite syntax-propertize-function that delegates syntax recognition to respective submode functions. For users, this means regular expressions in js-mode and string interpolations and percent literals in ruby-mode. ** Indentation More consistent indentation behavior, the default implementation delegates to the submode at the end of the indentation. The major mode can provide its own implementation by setting mmm-indent-line-function, to handle specific mode combinations better. * Changes in MMM Mode 0.4.8 ** Delimiter Regions The delimiters which mark off submode regions now have their own overlays. They can be highlighted if you so desire using appropriate class arguments and/or the variable mmm-delimiter-face. They are also in an appropriate major mode, or non-mode as the case may be. ** Nested Submodes Nested submodes are now vaguely supported. ** RPM Spec File An RPM spec file, contributed by , is now included for people who wish to build their own SRPM to install from. ** New Submode Classes Many thanks to Joe Kelsey for writing a very intelligent class for editing Noweb files, and to Alan Shutko for one for CWeb files. We also have a mode for SGML DTD definitions from Yann Dirson. ** Numerous bugfixes and small improvements * Changes in MMM Mode 0.4.7 ** Multiple Decoration Levels You now have finer control over how colorful your submode regions are, via `mmm-submode-decoration-level'. Level 0 turns coloring off--no messing around with faces required. Level 1 (default) is the same as in previous versions. Level 2 colors regions according to function: initialization, cleanup, output, declaration, comment, etc. ** Preferred Major Modes The variable `mmm-major-mode-preferences' lets you tell MMM what modes you prefer for different programming languages and they will be used by all submode classes. ** New Submode Classes New submode classes for JSP and ePerl are included. A major bug in the handling of embedded Java (and other C-type languages) was fixed, so the JSP class should work consistently. * MMM Mode 0.4.6 is a bug-fix release with one user-visible change: ** New Submode Class for RPM Spec Files Contributed by Marcus Harnisch, the `rpm' submode class allows editing appropriate parts of RPM spec files in shell-script mode. * Changes in MMM Mode 0.4.5 ** Font-Lock works again in XEmacs The MMM code to handle font-locking broke in XEmacs several versions back due to differences in the font-lock implementation between Emacs and XEmacs. It appears to be working once again. ** Here-Document submode class improved Here-document names such as <', rather than `C-c % ' as in previous versions. Key sequences of the form `C-c % ' are now reserved for submode region insertion. The old behavior can be restored by setting the variable `mmm-use-old-command-keys' to a non-nil value before MMM Mode is loaded--then insertion commands are bound to `C-c % C-' sequences. ** New Global Mode added MMM Global Mode can now turn MMM Mode on automatically in all buffers, or only in buffers that have associated submode classes. It replaces the previous function `mmm-add-find-file-hook', which still works for now. A side effect of this change is that it is no longer necessary to use `mmm-add-mode-ext-class': `mmm-mode-ext-classes-alist' can be modified directly. The hack used by MMM Global Mode to insinuate itself into all buffers is different from, but vaguely similar to, the one used by FSF Emacs' Global Font Lock Mode. In order that future writers of global modes don't have to reinvent the wheel, MMM Global Mode provides the hook `mmm-major-mode-hook' which is run (in theory) whenever a major mode starts up. Perhaps in future this will be provided in a separate package. ** Automatic submode region insertion commands Submode classes can now define skeletons for automatic insertion of submode regions with delimiters. For example, when using the Mason class, the key sequence `C-c % %' will (by default) insert the text `<% -!- %>' with point where indicated and submode region already present. These commands also wrap around words as described in the documentation of `skeleton-insert'. ** Info Documentation File MMM Mode now has an (admittedly incomplete) manual in Texinfo format. It can be found in the files `mmm.info' or `mmm.texinfo' in the distribution. ** Automatic Installation MMM Mode now uses GNU automake/autoconf for ease of installation. See the files README and INSTALL for more information. ** Changed submode class specification format This change affects only people who define their own submode classes. The format for defining submode classes has changed; it now uses keyword arguments for clarity and has a few more possible arguments, including skeletons for submode region insertion. mmm-mode-0.5.1/mmm-class.el0000664000175000017500000003007712106045366012375 00000000000000;;; mmm-class.el --- MMM submode class variables and functions ;; Copyright (C) 2000, 2004 by Michael Abraham Shulman ;; Author: Michael Abraham Shulman ;;{{{ GPL ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file contains variable and function definitions for ;; manipulating and applying MMM submode classes. See `mmm-vars.el' ;; for variables that list classes. ;;; Code: (require 'cl) (require 'mmm-vars) (require 'mmm-region) ;;; CLASS SPECIFICATIONS ;;{{{ Get Class Specifications (defun mmm-get-class-spec (class) "Get the class specification for CLASS. CLASS can be either a symbol to look up in `mmm-classes-alist' or a class specifier itself." (cond ((symbolp class) ; A symbol must be looked up (or (cdr (assq class mmm-classes-alist)) (and (cadr (assq class mmm-autoloaded-classes)) (load (cadr (assq class mmm-autoloaded-classes))) (cdr (assq class mmm-classes-alist))) (signal 'mmm-invalid-submode-class (list class)))) ((listp class) ; A list must be a class spec class) (t (signal 'mmm-invalid-submode-class (list class))))) ;;}}} ;;{{{ Get and Set Class Parameters (defun mmm-get-class-parameter (class param) "Get the value of the parameter PARAM for CLASS, or nil if none." (cadr (member param (mmm-get-class-spec class)))) (defun mmm-set-class-parameter (class param value) "Set the value of the parameter PARAM for CLASS to VALUE. Creates a new parameter if one is not present." (let* ((spec (mmm-get-class-spec class)) (current (member param spec))) (if current (setcar (cdr current) value) (nconc spec (list param value))))) ;;}}} ;;{{{ Apply Classes (defun* mmm-apply-class (class &optional (start (point-min)) (stop (point-max)) face) "Apply the submode class CLASS from START to STOP in FACE. If FACE is nil, the face for CLASS is used, or the default face if none is specified by CLASS." ;; The "special" class t means do nothing. It is used to turn on ;; MMM Mode without applying any classes. (unless (eq class t) (apply #'mmm-ify :start start :stop stop (append (mmm-get-class-spec class) (list :face face))) (mmm-run-class-hook class) ;; Hack in case class hook sets mmm-buffer-mode-display-name etc. (mmm-set-mode-line))) (defun* mmm-apply-classes (classes &key (start (point-min)) (stop (point-max)) face) "Apply all submode classes in CLASSES, in order. All classes are applied regardless of any errors that may occur in other classes. If any errors occur, `mmm-apply-classes' exits with an error once all classes have been applied." (let (invalid-classes) (dolist (class classes) (condition-case err (mmm-apply-class class start stop face) (mmm-invalid-submode-class ;; Save the name of the invalid class, so we can report them ;; all together at the end. (add-to-list 'invalid-classes (second err))))) (when invalid-classes (signal 'mmm-invalid-submode-class invalid-classes)))) ;;}}} ;;{{{ Apply All Classes (defun* mmm-apply-all (&key (start (point-min)) (stop (point-max))) "MMM-ify from START to STOP by all submode classes. The classes come from mode/ext, `mmm-classes', `mmm-global-classes', and interactive history." (mmm-clear-overlays start stop 'strict) (mmm-apply-classes (mmm-get-all-classes t) :start start :stop stop) (mmm-update-submode-region) (syntax-ppss-flush-cache start) (mmm-refontify-maybe start stop)) ;;}}} ;;; BUFFER SCANNING ;;{{{ Scan for Regions (defun* mmm-ify (&rest all &key classes handler submode match-submode (start (point-min)) (stop (point-max)) front back save-matches (case-fold-search t) (beg-sticky (not (number-or-marker-p front))) (end-sticky (not (number-or-marker-p back))) include-front include-back (front-offset 0) (back-offset 0) (front-delim nil) (back-delim nil) (delimiter-mode mmm-delimiter-mode) front-face back-face front-verify back-verify front-form back-form creation-hook face match-face save-name match-name (front-match 0) (back-match 0) end-not-begin ;insert private &allow-other-keys ) "Create submode regions from START to STOP according to arguments. If CLASSES is supplied, it must be a list of valid CLASSes. Otherwise, the rest of the arguments are for an actual class being applied. See `mmm-classes-alist' for information on what they all mean." ;; Make sure we get the default values in the `all' list. (setq all (append all (list :start start :stop stop :beg-sticky beg-sticky :end-sticky end-sticky :front-offset front-offset :back-offset back-offset :front-delim front-delim :back-delim back-delim :front-match 0 :back-match 0 ))) (cond ;; If we have a class list, apply them all. (classes (mmm-apply-classes classes :start start :stop stop :face face)) ;; Otherwise, apply this class. ;; If we have a handler, call it. (handler (apply handler all)) ;; Otherwise, we search from START to STOP for submode regions, ;; continuining over errors, until we don't find any more. If FRONT ;; and BACK are number-or-markers, this should only execute once. (t (mmm-save-all (goto-char start) (loop for (beg end front-pos back-pos matched-front matched-back matched-submode matched-face matched-name invalid-resume ok-resume) = (apply #'mmm-match-region :start (point) all) while beg if end ; match-submode, if present, succeeded. do (condition-case nil (progn (mmm-make-region (or matched-submode submode) beg end :face (or matched-face face) :front front-pos :back back-pos :evaporation 'front :match-front matched-front :match-back matched-back :beg-sticky beg-sticky :end-sticky end-sticky :name matched-name :delimiter-mode delimiter-mode :front-face front-face :back-face back-face :creation-hook creation-hook ) (goto-char ok-resume)) ;; If our region is invalid, go back to the end of the ;; front match and continue on. (mmm-error (goto-char invalid-resume))) ;; If match-submode was unable to find a match, go back to ;; the end of the front match and continue on. else do (goto-char invalid-resume) ))))) ;;}}} ;;{{{ Match Regions (defun* mmm-match-region (&key start stop front back front-verify back-verify front-delim back-delim include-front include-back front-offset back-offset front-form back-form save-matches match-submode match-face front-match back-match end-not-begin save-name match-name &allow-other-keys) "Find the first valid region between point and STOP. Return \(BEG END FRONT-POS BACK-POS FRONT-FORM BACK-FORM SUBMODE FACE NAME INVALID-RESUME OK-RESUME) specifying the region. See `mmm-match-and-verify' for the valid values of FRONT and BACK \(markers, regexps, or functions). A nil value for END means that MATCH-SUBMODE failed to find a valid submode. INVALID-RESUME is the point at which the search should continue if the region is invalid, and OK-RESUME if the region is valid." (when (mmm-match-and-verify front start stop front-verify) (let ((beg (mmm-match->point include-front front-offset front-match)) (front-pos (if front-delim (mmm-match->point t front-delim front-match) nil)) (invalid-resume (match-end front-match)) (front-form (mmm-get-form front-form))) (let ((submode (if match-submode (condition-case nil (mmm-save-all (funcall match-submode front-form)) (mmm-no-matching-submode (return-from mmm-match-region (values beg nil nil nil nil nil nil nil nil invalid-resume nil)))) nil)) (name (cond ((functionp match-name) (mmm-save-all (funcall match-name front-form))) ((stringp match-name) (if save-name (mmm-format-matches match-name) match-name)))) (face (cond ((functionp match-face) (mmm-save-all (funcall match-face front-form))) (match-face (cdr (assoc front-form match-face)))))) (when (mmm-match-and-verify (if save-matches (mmm-format-matches back) back) beg stop back-verify) (let* ((end (mmm-match->point (not include-back) back-offset back-match)) (back-pos (if back-delim (mmm-match->point nil back-delim back-match) nil)) (back-form (mmm-get-form back-form)) (ok-resume (if end-not-begin (match-end back-match) end))) (values beg end front-pos back-pos front-form back-form submode face name invalid-resume ok-resume))))))) (defun mmm-match->point (beginp offset match) "Find a point of starting or stopping from the match data. If BEGINP, start at \(match-beginning MATCH), else \(match-end MATCH), and move OFFSET. Handles all values of OFFSET--see `mmm-classes-alist'." (save-excursion (goto-char (if beginp (match-beginning match) (match-end match))) (dolist (spec (if (listp offset) offset (list offset))) (if (numberp spec) (forward-char (or spec 0)) (funcall spec))) (point))) (defun mmm-match-and-verify (pos start stop &optional verify) "Find first match for POS between point and STOP satisfying VERIFY. Return non-nil if a match was found, and set match data. POS can be a number-or-marker, a regexp, or a function. If POS is a number-or-marker, it is used as-is. If it is a string, it is searched for as a regexp until VERIFY returns non-nil. If it is a function, it is called with argument STOP and must return non-nil iff a match is found, and set the match data. Note that VERIFY is ignored unless POS is a regexp." (cond ;; A marker can be used as-is, but only if it's in bounds. ((and (number-or-marker-p pos) (>= pos start) (<= pos stop)) (goto-char pos) (looking-at "")) ; Set the match data ;; Strings are searched for as regexps. ((stringp pos) (loop always (re-search-forward pos stop 'limit) until (or (not verify) (mmm-save-all (funcall verify))))) ;; Otherwise it must be a function. ((functionp pos) (funcall pos stop)))) ;;}}} ;;{{{ Get Delimiter Forms (defun mmm-get-form (form) "Return the delimiter form specified by FORM. If FORM is nil, call `mmm-default-get-form'. If FORM is a string, return it. If FORM is a function, call it. If FORM is a list, return its `car' \(usually in this case, FORM is a one-element list containing a function to be used as the delimiter form." (cond ((stringp form) form) ((not form) (mmm-default-get-form)) ((functionp form) (mmm-save-all (funcall form))) ((listp form) (car form)))) (defun mmm-default-get-form () (regexp-quote (match-string 0))) ;;}}} (provide 'mmm-class) ;;; mmm-class.el ends here mmm-mode-0.5.1/texinfo.tex0000664000175000017500000054550712043063215012362 00000000000000% texinfo.tex -- TeX macros to handle Texinfo files. % % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % \def\texinfoversion{1999-01-05}% % % Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 94, 95, 96, 97, 98 % Free Software Foundation, Inc. % % This texinfo.tex file is free software; you can redistribute it and/or % modify it under the terms of the GNU General Public License as % published by the Free Software Foundation; either version 2, or (at % your option) any later version. % % This texinfo.tex file is distributed in the hope that it will be % useful, but WITHOUT ANY WARRANTY; without even the implied warranty % of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU % General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this texinfo.tex file; see the file COPYING. If not, write % to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, % Boston, MA 02111-1307, USA. % % In other words, you are welcome to use, share and improve this program. % You are forbidden to forbid anyone else to use, share and improve % what you give them. Help stamp out software-hoarding! % % Please try the latest version of texinfo.tex before submitting bug % reports; you can get the latest version from: % ftp://ftp.gnu.org/pub/gnu/texinfo.tex % /home/gd/gnu/doc/texinfo.tex on the GNU machines. % (and all GNU mirrors, see http://www.gnu.org/order/ftp.html) % ftp://tug.org/tex/texinfo.tex % ftp://ctan.org/macros/texinfo/texinfo.tex % (and all CTAN mirrors, finger ctan@ctan.org for a list). % The texinfo.tex in the texinfo distribution itself could well be out % of date, so if that's what you're using, please check. % % Send bug reports to bug-texinfo@gnu.org. % Please include a precise test case in each bug report, % including a complete document with which we can reproduce the problem. % % To process a Texinfo manual with TeX, it's most reliable to use the % texi2dvi shell script that comes with the distribution. For simple % manuals, however, you can get away with: % tex foo.texi % texindex foo.?? % tex foo.texi % tex foo.texi % dvips foo.dvi -o # or whatever, to process the dvi file. % The extra runs of TeX get the cross-reference information correct. % Sometimes one run after texindex suffices, and sometimes you need more % than two; texi2dvi does it as many times as necessary. \message{Loading texinfo [version \texinfoversion]:} % If in a .fmt file, print the version number % and turn on active characters that we couldn't do earlier because % they might have appeared in the input file name. \everyjob{\message{[Texinfo version \texinfoversion]}% \catcode`+=\active \catcode`\_=\active} % Save some parts of plain tex whose names we will redefine. \let\ptexb=\b \let\ptexbullet=\bullet \let\ptexc=\c \let\ptexcomma=\, \let\ptexdot=\. \let\ptexdots=\dots \let\ptexend=\end \let\ptexequiv=\equiv \let\ptexexclam=\! \let\ptexi=\i \let\ptexlbrace=\{ \let\ptexrbrace=\} \let\ptexstar=\* \let\ptext=\t % We never want plain's outer \+ definition in Texinfo. % For @tex, we can use \tabalign. \let\+ = \relax \message{Basics,} \chardef\other=12 % If this character appears in an error message or help string, it % starts a new line in the output. \newlinechar = `^^J % Set up fixed words for English if not already set. \ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi \ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi \ifx\putwordfile\undefined \gdef\putwordfile{file}\fi \ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi \ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi \ifx\putwordon\undefined \gdef\putwordon{on}\fi \ifx\putwordpage\undefined \gdef\putwordpage{page}\fi \ifx\putwordsection\undefined \gdef\putwordsection{section}\fi \ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi \ifx\putwordsee\undefined \gdef\putwordsee{see}\fi \ifx\putwordSee\undefined \gdef\putwordSee{See}\fi \ifx\putwordShortContents\undefined \gdef\putwordShortContents{Short Contents}\fi \ifx\putwordTableofContents\undefined\gdef\putwordTableofContents{Table of Contents}\fi % Ignore a token. % \def\gobble#1{} \hyphenation{ap-pen-dix} \hyphenation{mini-buf-fer mini-buf-fers} \hyphenation{eshell} \hyphenation{white-space} % Margin to add to right of even pages, to left of odd pages. \newdimen \bindingoffset \newdimen \normaloffset \newdimen\pagewidth \newdimen\pageheight % Sometimes it is convenient to have everything in the transcript file % and nothing on the terminal. We don't just call \tracingall here, % since that produces some useless output on the terminal. % \def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% \ifx\eTeXversion\undefined \def\loggingall{\tracingcommands2 \tracingstats2 \tracingpages1 \tracingoutput1 \tracinglostchars1 \tracingmacros2 \tracingparagraphs1 \tracingrestores1 \showboxbreadth\maxdimen\showboxdepth\maxdimen }% \else \def\loggingall{\tracingcommands3 \tracingstats2 \tracingpages1 \tracingoutput1 \tracinglostchars1 \tracingmacros2 \tracingparagraphs1 \tracingrestores1 \tracingscantokens1 \tracingassigns1 \tracingifs1 \tracinggroups1 \tracingnesting2 \showboxbreadth\maxdimen\showboxdepth\maxdimen }% \fi % For @cropmarks command. % Do @cropmarks to get crop marks. % \newif\ifcropmarks \let\cropmarks = \cropmarkstrue % % Dimensions to add cropmarks at corners. % Added by P. A. MacKay, 12 Nov. 1986 % \newdimen\outerhsize \newdimen\outervsize % set by the paper size routines \newdimen\cornerlong \cornerlong=1pc \newdimen\cornerthick \cornerthick=.3pt \newdimen\topandbottommargin \topandbottommargin=.75in % Main output routine. \chardef\PAGE = 255 \output = {\onepageout{\pagecontents\PAGE}} \newbox\headlinebox \newbox\footlinebox % \onepageout takes a vbox as an argument. Note that \pagecontents % does insertions, but you have to call it yourself. \def\onepageout#1{% \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi % \ifodd\pageno \advance\hoffset by \bindingoffset \else \advance\hoffset by -\bindingoffset\fi % % Do this outside of the \shipout so @code etc. will be expanded in % the headline as they should be, not taken literally (outputting ''code). \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% % {% % Have to do this stuff outside the \shipout because we want it to % take effect in \write's, yet the group defined by the \vbox ends % before the \shipout runs. % \escapechar = `\\ % use backslash in output files. \indexdummies % don't expand commands in the output. \normalturnoffactive % \ in index entries must not stay \, e.g., if % the page break happens to be in the middle of an example. \shipout\vbox{% \ifcropmarks \vbox to \outervsize\bgroup \hsize = \outerhsize \vskip-\topandbottommargin \vtop to0pt{% \line{\ewtop\hfil\ewtop}% \nointerlineskip \line{% \vbox{\moveleft\cornerthick\nstop}% \hfill \vbox{\moveright\cornerthick\nstop}% }% \vss}% \vskip\topandbottommargin \line\bgroup \hfil % center the page within the outer (page) hsize. \ifodd\pageno\hskip\bindingoffset\fi \vbox\bgroup \fi % \unvbox\headlinebox \pagebody{#1}% \ifdim\ht\footlinebox > 0pt % Only leave this space if the footline is nonempty. % (We lessened \vsize for it in \oddfootingxxx.) % The \baselineskip=24pt in plain's \makefootline has no effect. \vskip 2\baselineskip \unvbox\footlinebox \fi % \ifcropmarks \egroup % end of \vbox\bgroup \hfil\egroup % end of (centering) \line\bgroup \vskip\topandbottommargin plus1fill minus1fill \boxmaxdepth = \cornerthick \vbox to0pt{\vss \line{% \vbox{\moveleft\cornerthick\nsbot}% \hfill \vbox{\moveright\cornerthick\nsbot}% }% \nointerlineskip \line{\ewbot\hfil\ewbot}% }% \egroup % \vbox from first cropmarks clause \fi }% end of \shipout\vbox }% end of group with \turnoffactive \advancepageno \ifnum\outputpenalty>-20000 \else\dosupereject\fi } \newinsert\margin \dimen\margin=\maxdimen \def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} {\catcode`\@ =11 \gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi % marginal hacks, juha@viisa.uucp (Juha Takala) \ifvoid\margin\else % marginal info is present \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi \dimen@=\dp#1 \unvbox#1 \ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi \ifr@ggedbottom \kern-\dimen@ \vfil \fi} } % Here are the rules for the cropmarks. Note that they are % offset so that the space between them is truly \outerhsize or \outervsize % (P. A. MacKay, 12 November, 1986) % \def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} \def\nstop{\vbox {\hrule height\cornerthick depth\cornerlong width\cornerthick}} \def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} \def\nsbot{\vbox {\hrule height\cornerlong depth\cornerthick width\cornerthick}} % Parse an argument, then pass it to #1. The argument is the rest of % the input line (except we remove a trailing comment). #1 should be a % macro which expects an ordinary undelimited TeX argument. % \def\parsearg#1{% \let\next = #1% \begingroup \obeylines \futurelet\temp\parseargx } % If the next token is an obeyed space (from an @example environment or % the like), remove it and recurse. Otherwise, we're done. \def\parseargx{% % \obeyedspace is defined far below, after the definition of \sepspaces. \ifx\obeyedspace\temp \expandafter\parseargdiscardspace \else \expandafter\parseargline \fi } % Remove a single space (as the delimiter token to the macro call). {\obeyspaces % \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} {\obeylines % \gdef\parseargline#1^^M{% \endgroup % End of the group started in \parsearg. % % First remove any @c comment, then any @comment. % Result of each macro is put in \toks0. \argremovec #1\c\relax % \expandafter\argremovecomment \the\toks0 \comment\relax % % % Call the caller's macro, saved as \next in \parsearg. \expandafter\next\expandafter{\the\toks0}% }% } % Since all \c{,omment} does is throw away the argument, we can let TeX % do that for us. The \relax here is matched by the \relax in the call % in \parseargline; it could be more or less anything, its purpose is % just to delimit the argument to the \c. \def\argremovec#1\c#2\relax{\toks0 = {#1}} \def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} % \argremovec{,omment} might leave us with trailing spaces, though; e.g., % @end itemize @c foo % will have two active spaces as part of the argument with the % `itemize'. Here we remove all active spaces from #1, and assign the % result to \toks0. % % This loses if there are any *other* active characters besides spaces % in the argument -- _ ^ +, for example -- since they get expanded. % Fortunately, Texinfo does not define any such commands. (If it ever % does, the catcode of the characters in questionwill have to be changed % here.) But this means we cannot call \removeactivespaces as part of % \argremovec{,omment}, since @c uses \parsearg, and thus the argument % that \parsearg gets might well have any character at all in it. % \def\removeactivespaces#1{% \begingroup \ignoreactivespaces \edef\temp{#1}% \global\toks0 = \expandafter{\temp}% \endgroup } % Change the active space to expand to nothing. % \begingroup \obeyspaces \gdef\ignoreactivespaces{\obeyspaces\let =\empty} \endgroup \def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} %% These are used to keep @begin/@end levels from running away %% Call \inENV within environments (after a \begingroup) \newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} \def\ENVcheck{% \ifENV\errmessage{Still within an environment; press RETURN to continue} \endgroup\fi} % This is not perfect, but it should reduce lossage % @begin foo is the same as @foo, for now. \newhelp\EMsimple{Press RETURN to continue.} \outer\def\begin{\parsearg\beginxxx} \def\beginxxx #1{% \expandafter\ifx\csname #1\endcsname\relax {\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else \csname #1\endcsname\fi} % @end foo executes the definition of \Efoo. % \def\end{\parsearg\endxxx} \def\endxxx #1{% \removeactivespaces{#1}% \edef\endthing{\the\toks0}% % \expandafter\ifx\csname E\endthing\endcsname\relax \expandafter\ifx\csname \endthing\endcsname\relax % There's no \foo, i.e., no ``environment'' foo. \errhelp = \EMsimple \errmessage{Undefined command `@end \endthing'}% \else \unmatchedenderror\endthing \fi \else % Everything's ok; the right environment has been started. \csname E\endthing\endcsname \fi } % There is an environment #1, but it hasn't been started. Give an error. % \def\unmatchedenderror#1{% \errhelp = \EMsimple \errmessage{This `@end #1' doesn't have a matching `@#1'}% } % Define the control sequence \E#1 to give an unmatched @end error. % \def\defineunmatchedend#1{% \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% } % Single-spacing is done by various environments (specifically, in % \nonfillstart and \quotations). \newskip\singlespaceskip \singlespaceskip = 12.5pt \def\singlespace{% % Why was this kern here? It messes up equalizing space above and below % environments. --karl, 6may93 %{\advance \baselineskip by -\singlespaceskip %\kern \baselineskip}% \setleading \singlespaceskip } %% Simple single-character @ commands % @@ prints an @ % Kludge this until the fonts are right (grr). \def\@{{\tt\char64}} % This is turned off because it was never documented % and you can use @w{...} around a quote to suppress ligatures. %% Define @` and @' to be the same as ` and ' %% but suppressing ligatures. %\def\`{{`}} %\def\'{{'}} % Used to generate quoted braces. \def\mylbrace {{\tt\char123}} \def\myrbrace {{\tt\char125}} \let\{=\mylbrace \let\}=\myrbrace \begingroup % Definitions to produce actual \{ & \} command in an index. \catcode`\{ = 12 \catcode`\} = 12 \catcode`\[ = 1 \catcode`\] = 2 \catcode`\@ = 0 \catcode`\\ = 12 @gdef@lbracecmd[\{]% @gdef@rbracecmd[\}]% @endgroup % Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent % Others are defined by plain TeX: @` @' @" @^ @~ @= @v @H. \let\, = \c \let\dotaccent = \. \def\ringaccent#1{{\accent23 #1}} \let\tieaccent = \t \let\ubaraccent = \b \let\udotaccent = \d % Other special characters: @questiondown @exclamdown % Plain TeX defines: @AA @AE @O @OE @L (and lowercase versions) @ss. \def\questiondown{?`} \def\exclamdown{!`} % Dotless i and dotless j, used for accents. \def\imacro{i} \def\jmacro{j} \def\dotless#1{% \def\temp{#1}% \ifx\temp\imacro \ptexi \else\ifx\temp\jmacro \j \else \errmessage{@dotless can be used only with i or j}% \fi\fi } % Be sure we're in horizontal mode when doing a tie, since we make space % equivalent to this in @example-like environments. Otherwise, a space % at the beginning of a line will start with \penalty -- and % since \penalty is valid in vertical mode, we'd end up putting the % penalty on the vertical list instead of in the new paragraph. {\catcode`@ = 11 % Avoid using \@M directly, because that causes trouble % if the definition is written into an index file. \global\let\tiepenalty = \@M \gdef\tie{\leavevmode\penalty\tiepenalty\ } } % @: forces normal size whitespace following. \def\:{\spacefactor=1000 } % @* forces a line break. \def\*{\hfil\break\hbox{}\ignorespaces} % @. is an end-of-sentence period. \def\.{.\spacefactor=3000 } % @! is an end-of-sentence bang. \def\!{!\spacefactor=3000 } % @? is an end-of-sentence query. \def\?{?\spacefactor=3000 } % @w prevents a word break. Without the \leavevmode, @w at the % beginning of a paragraph, when TeX is still in vertical mode, would % produce a whole line of output instead of starting the paragraph. \def\w#1{\leavevmode\hbox{#1}} % @group ... @end group forces ... to be all on one page, by enclosing % it in a TeX vbox. We use \vtop instead of \vbox to construct the box % to keep its height that of a normal line. According to the rules for % \topskip (p.114 of the TeXbook), the glue inserted is % max (\topskip - \ht (first item), 0). If that height is large, % therefore, no glue is inserted, and the space between the headline and % the text is small, which looks bad. % \def\group{\begingroup \ifnum\catcode13=\active \else \errhelp = \groupinvalidhelp \errmessage{@group invalid in context where filling is enabled}% \fi % % The \vtop we start below produces a box with normal height and large % depth; thus, TeX puts \baselineskip glue before it, and (when the % next line of text is done) \lineskip glue after it. (See p.82 of % the TeXbook.) Thus, space below is not quite equal to space % above. But it's pretty close. \def\Egroup{% \egroup % End the \vtop. \endgroup % End the \group. }% % \vtop\bgroup % We have to put a strut on the last line in case the @group is in % the midst of an example, rather than completely enclosing it. % Otherwise, the interline space between the last line of the group % and the first line afterwards is too small. But we can't put the % strut in \Egroup, since there it would be on a line by itself. % Hence this just inserts a strut at the beginning of each line. \everypar = {\strut}% % % Since we have a strut on every line, we don't need any of TeX's % normal interline spacing. \offinterlineskip % % OK, but now we have to do something about blank % lines in the input in @example-like environments, which normally % just turn into \lisppar, which will insert no space now that we've % turned off the interline space. Simplest is to make them be an % empty paragraph. \ifx\par\lisppar \edef\par{\leavevmode \par}% % % Reset ^^M's definition to new definition of \par. \obeylines \fi % % Do @comment since we are called inside an environment such as % @example, where each end-of-line in the input causes an % end-of-line in the output. We don't want the end-of-line after % the `@group' to put extra space in the output. Since @group % should appear on a line by itself (according to the Texinfo % manual), we don't worry about eating any user text. \comment } % % TeX puts in an \escapechar (i.e., `@') at the beginning of the help % message, so this ends up printing `@group can only ...'. % \newhelp\groupinvalidhelp{% group can only be used in environments such as @example,^^J% where each line of input produces a line of output.} % @need space-in-mils % forces a page break if there is not space-in-mils remaining. \newdimen\mil \mil=0.001in \def\need{\parsearg\needx} % Old definition--didn't work. %\def\needx #1{\par % %% This method tries to make TeX break the page naturally %% if the depth of the box does not fit. %{\baselineskip=0pt% %\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak %\prevdepth=-1000pt %}} \def\needx#1{% % Go into vertical mode, so we don't make a big box in the middle of a % paragraph. \par % % Don't add any leading before our big empty box, but allow a page % break, since the best break might be right here. \allowbreak \nointerlineskip \vtop to #1\mil{\vfil}% % % TeX does not even consider page breaks if a penalty added to the % main vertical list is 10000 or more. But in order to see if the % empty box we just added fits on the page, we must make it consider % page breaks. On the other hand, we don't want to actually break the % page after the empty box. So we use a penalty of 9999. % % There is an extremely small chance that TeX will actually break the % page at this \penalty, if there are no other feasible breakpoints in % sight. (If the user is using lots of big @group commands, which % almost-but-not-quite fill up a page, TeX will have a hard time doing % good page breaking, for example.) However, I could not construct an % example where a page broke at this \penalty; if it happens in a real % document, then we can reconsider our strategy. \penalty9999 % % Back up by the size of the box, whether we did a page break or not. \kern -#1\mil % % Do not allow a page break right after this kern. \nobreak } % @br forces paragraph break \let\br = \par % @dots{} output an ellipsis using the current font. % We do .5em per period so that it has the same spacing in a typewriter % font as three actual period characters. % \def\dots{% \leavevmode \hbox to 1.5em{% \hskip 0pt plus 0.25fil minus 0.25fil .\hss.\hss.% \hskip 0pt plus 0.5fil minus 0.5fil }% } % @enddots{} is an end-of-sentence ellipsis. % \def\enddots{% \leavevmode \hbox to 2em{% \hskip 0pt plus 0.25fil minus 0.25fil .\hss.\hss.\hss.% \hskip 0pt plus 0.5fil minus 0.5fil }% \spacefactor=3000 } % @page forces the start of a new page % \def\page{\par\vfill\supereject} % @exdent text.... % outputs text on separate line in roman font, starting at standard page margin % This records the amount of indent in the innermost environment. % That's how much \exdent should take out. \newskip\exdentamount % This defn is used inside fill environments such as @defun. \def\exdent{\parsearg\exdentyyy} \def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} % This defn is used inside nofill environments such as @example. \def\nofillexdent{\parsearg\nofillexdentyyy} \def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount \leftline{\hskip\leftskip{\rm#1}}}} % @inmargin{TEXT} puts TEXT in the margin next to the current paragraph. \def\inmargin#1{% \strut\vadjust{\nobreak\kern-\strutdepth \vtop to \strutdepth{\baselineskip\strutdepth\vss \llap{\rightskip=\inmarginspacing \vbox{\noindent #1}}\null}}} \newskip\inmarginspacing \inmarginspacing=1cm \def\strutdepth{\dp\strutbox} %\hbox{{\rm#1}}\hfil\break}} % @include file insert text of that file as input. % Allow normal characters that we make active in the argument (a file name). \def\include{\begingroup \catcode`\\=12 \catcode`~=12 \catcode`^=12 \catcode`_=12 \catcode`|=12 \catcode`<=12 \catcode`>=12 \catcode`+=12 \parsearg\includezzz} % Restore active chars for included file. \def\includezzz#1{\endgroup\begingroup % Read the included file in a group so nested @include's work. \def\thisfile{#1}% \input\thisfile \endgroup} \def\thisfile{} % @center line outputs that line, centered \def\center{\parsearg\centerzzz} \def\centerzzz #1{{\advance\hsize by -\leftskip \advance\hsize by -\rightskip \centerline{#1}}} % @sp n outputs n lines of vertical space \def\sp{\parsearg\spxxx} \def\spxxx #1{\vskip #1\baselineskip} % @comment ...line which is ignored... % @c is the same as @comment % @ignore ... @end ignore is another way to write a comment \def\comment{\begingroup \catcode`\^^M=\other% \catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% \commentxxx} {\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} \let\c=\comment % @paragraphindent is defined for the Info formatting commands only. \let\paragraphindent=\comment % Prevent errors for section commands. % Used in @ignore and in failing conditionals. \def\ignoresections{% \let\chapter=\relax \let\unnumbered=\relax \let\top=\relax \let\unnumberedsec=\relax \let\unnumberedsection=\relax \let\unnumberedsubsec=\relax \let\unnumberedsubsection=\relax \let\unnumberedsubsubsec=\relax \let\unnumberedsubsubsection=\relax \let\section=\relax \let\subsec=\relax \let\subsubsec=\relax \let\subsection=\relax \let\subsubsection=\relax \let\appendix=\relax \let\appendixsec=\relax \let\appendixsection=\relax \let\appendixsubsec=\relax \let\appendixsubsection=\relax \let\appendixsubsubsec=\relax \let\appendixsubsubsection=\relax \let\contents=\relax \let\smallbook=\relax \let\titlepage=\relax } % Used in nested conditionals, where we have to parse the Texinfo source % and so want to turn off most commands, in case they are used % incorrectly. % \def\ignoremorecommands{% \let\defcodeindex = \relax \let\defcv = \relax \let\deffn = \relax \let\deffnx = \relax \let\defindex = \relax \let\defivar = \relax \let\defmac = \relax \let\defmethod = \relax \let\defop = \relax \let\defopt = \relax \let\defspec = \relax \let\deftp = \relax \let\deftypefn = \relax \let\deftypefun = \relax \let\deftypevar = \relax \let\deftypevr = \relax \let\defun = \relax \let\defvar = \relax \let\defvr = \relax \let\ref = \relax \let\xref = \relax \let\printindex = \relax \let\pxref = \relax \let\settitle = \relax \let\setchapternewpage = \relax \let\setchapterstyle = \relax \let\everyheading = \relax \let\evenheading = \relax \let\oddheading = \relax \let\everyfooting = \relax \let\evenfooting = \relax \let\oddfooting = \relax \let\headings = \relax \let\include = \relax \let\lowersections = \relax \let\down = \relax \let\raisesections = \relax \let\up = \relax \let\set = \relax \let\clear = \relax \let\item = \relax } % Ignore @ignore ... @end ignore. % \def\ignore{\doignore{ignore}} % Ignore @ifinfo, @ifhtml, @ifnottex, @html, @menu, and @direntry text. % \def\ifinfo{\doignore{ifinfo}} \def\ifhtml{\doignore{ifhtml}} \def\ifnottex{\doignore{ifnottex}} \def\html{\doignore{html}} \def\menu{\doignore{menu}} \def\direntry{\doignore{direntry}} % @dircategory CATEGORY -- specify a category of the dir file % which this file should belong to. Ignore this in TeX. \let\dircategory = \comment % Ignore text until a line `@end #1'. % \def\doignore#1{\begingroup % Don't complain about control sequences we have declared \outer. \ignoresections % % Define a command to swallow text until we reach `@end #1'. % This @ is a catcode 12 token (that is the normal catcode of @ in % this texinfo.tex file). We change the catcode of @ below to match. \long\def\doignoretext##1@end #1{\enddoignore}% % % Make sure that spaces turn into tokens that match what \doignoretext wants. \catcode32 = 10 % % Ignore braces, too, so mismatched braces don't cause trouble. \catcode`\{ = 9 \catcode`\} = 9 % % We must not have @c interpreted as a control sequence. \catcode`\@ = 12 % % Make the letter c a comment character so that the rest of the line % will be ignored. This way, the document can have (for example) % @c @end ifinfo % and the @end ifinfo will be properly ignored. % (We've just changed @ to catcode 12.) \catcode`\c = 14 % % And now expand that command. \doignoretext } % What we do to finish off ignored text. % \def\enddoignore{\endgroup\ignorespaces}% \newif\ifwarnedobs\warnedobsfalse \def\obstexwarn{% \ifwarnedobs\relax\else % We need to warn folks that they may have trouble with TeX 3.0. % This uses \immediate\write16 rather than \message to get newlines. \immediate\write16{} \immediate\write16{***WARNING*** for users of Unix TeX 3.0!} \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).} \immediate\write16{If you are running another version of TeX, relax.} \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.} \immediate\write16{ Then upgrade your TeX installation if you can.} \immediate\write16{ (See ftp://ftp.gnu.org/pub/gnu/TeX.README.)} \immediate\write16{If you are stuck with version 3.0, run the} \immediate\write16{ script ``tex3patch'' from the Texinfo distribution} \immediate\write16{ to use a workaround.} \immediate\write16{} \global\warnedobstrue \fi } % **In TeX 3.0, setting text in \nullfont hangs tex. For a % workaround (which requires the file ``dummy.tfm'' to be installed), % uncomment the following line: %%%%%\font\nullfont=dummy\let\obstexwarn=\relax % Ignore text, except that we keep track of conditional commands for % purposes of nesting, up to an `@end #1' command. % \def\nestedignore#1{% \obstexwarn % We must actually expand the ignored text to look for the @end % command, so that nested ignore constructs work. Thus, we put the % text into a \vbox and then do nothing with the result. To minimize % the change of memory overflow, we follow the approach outlined on % page 401 of the TeXbook: make the current font be a dummy font. % \setbox0 = \vbox\bgroup % Don't complain about control sequences we have declared \outer. \ignoresections % % Define `@end #1' to end the box, which will in turn undefine the % @end command again. \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}% % % We are going to be parsing Texinfo commands. Most cause no % trouble when they are used incorrectly, but some commands do % complicated argument parsing or otherwise get confused, so we % undefine them. % % We can't do anything about stray @-signs, unfortunately; % they'll produce `undefined control sequence' errors. \ignoremorecommands % % Set the current font to be \nullfont, a TeX primitive, and define % all the font commands to also use \nullfont. We don't use % dummy.tfm, as suggested in the TeXbook, because not all sites % might have that installed. Therefore, math mode will still % produce output, but that should be an extremely small amount of % stuff compared to the main input. % \nullfont \let\tenrm = \nullfont \let\tenit = \nullfont \let\tensl = \nullfont \let\tenbf = \nullfont \let\tentt = \nullfont \let\smallcaps = \nullfont \let\tensf = \nullfont % Similarly for index fonts (mostly for their use in % smallexample) \let\indrm = \nullfont \let\indit = \nullfont \let\indsl = \nullfont \let\indbf = \nullfont \let\indtt = \nullfont \let\indsc = \nullfont \let\indsf = \nullfont % % Don't complain when characters are missing from the fonts. \tracinglostchars = 0 % % Don't bother to do space factor calculations. \frenchspacing % % Don't report underfull hboxes. \hbadness = 10000 % % Do minimal line-breaking. \pretolerance = 10000 % % Do not execute instructions in @tex \def\tex{\doignore{tex}}% % Do not execute macro definitions. % `c' is a comment character, so the word `macro' will get cut off. \def\macro{\doignore{ma}}% } % @set VAR sets the variable VAR to an empty value. % @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. % % Since we want to separate VAR from REST-OF-LINE (which might be % empty), we can't just use \parsearg; we have to insert a space of our % own to delimit the rest of the line, and then take it out again if we % didn't need it. Make sure the catcode of space is correct to avoid % losing inside @example, for instance. % \def\set{\begingroup\catcode` =10 \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. \parsearg\setxxx} \def\setxxx#1{\setyyy#1 \endsetyyy} \def\setyyy#1 #2\endsetyyy{% \def\temp{#2}% \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. \fi \endgroup } % Can't use \xdef to pre-expand #2 and save some time, since \temp or % \next or other control sequences that we've defined might get us into % an infinite loop. Consider `@set foo @cite{bar}'. \def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} % @clear VAR clears (i.e., unsets) the variable VAR. % \def\clear{\parsearg\clearxxx} \def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} % @value{foo} gets the text saved in variable foo. % { \catcode`\_ = \active % % We might end up with active _ or - characters in the argument if % we're called from @code, as @code{@value{foo-bar_}}. So \let any % such active characters to their normal equivalents. \gdef\value{\begingroup \catcode`\-=12 \catcode`\_=12 \indexbreaks \let_\normalunderscore \valuexxx} } \def\valuexxx#1{\expandablevalue{#1}\endgroup} % We have this subroutine so that we can handle at least some @value's % properly in indexes (we \let\value to this in \indexdummies). Ones % whose names contain - or _ still won't work, but we can't do anything % about that. The command has to be fully expandable, since the result % winds up in the index file. This means that if the variable's value % contains other Texinfo commands, it's almost certain it will fail % (although perhaps we could fix that with sufficient work to do a % one-level expansion on the result, instead of complete). % \def\expandablevalue#1{% \expandafter\ifx\csname SET#1\endcsname\relax {[No value for ``#1'']}% \else \csname SET#1\endcsname \fi } % @ifset VAR ... @end ifset reads the `...' iff VAR has been defined % with @set. % \def\ifset{\parsearg\ifsetxxx} \def\ifsetxxx #1{% \expandafter\ifx\csname SET#1\endcsname\relax \expandafter\ifsetfail \else \expandafter\ifsetsucceed \fi } \def\ifsetsucceed{\conditionalsucceed{ifset}} \def\ifsetfail{\nestedignore{ifset}} \defineunmatchedend{ifset} % @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been % defined with @set, or has been undefined with @clear. % \def\ifclear{\parsearg\ifclearxxx} \def\ifclearxxx #1{% \expandafter\ifx\csname SET#1\endcsname\relax \expandafter\ifclearsucceed \else \expandafter\ifclearfail \fi } \def\ifclearsucceed{\conditionalsucceed{ifclear}} \def\ifclearfail{\nestedignore{ifclear}} \defineunmatchedend{ifclear} % @iftex, @ifnothtml, @ifnotinfo always succeed; we read the text % following, through the first @end iftex (etc.). Make `@end iftex' % (etc.) valid only after an @iftex. % \def\iftex{\conditionalsucceed{iftex}} \def\ifnothtml{\conditionalsucceed{ifnothtml}} \def\ifnotinfo{\conditionalsucceed{ifnotinfo}} \defineunmatchedend{iftex} \defineunmatchedend{ifnothtml} \defineunmatchedend{ifnotinfo} % We can't just want to start a group at @iftex (for example) and end it % at @end iftex, since then @set commands inside the conditional have no % effect (they'd get reverted at the end of the group). So we must % define \Eiftex to redefine itself to be its previous value. (We can't % just define it to fail again with an ``unmatched end'' error, since % the @ifset might be nested.) % \def\conditionalsucceed#1{% \edef\temp{% % Remember the current value of \E#1. \let\nece{prevE#1} = \nece{E#1}% % % At the `@end #1', redefine \E#1 to be its previous value. \def\nece{E#1}{\let\nece{E#1} = \nece{prevE#1}}% }% \temp } % We need to expand lots of \csname's, but we don't want to expand the % control sequences after we've constructed them. % \def\nece#1{\expandafter\noexpand\csname#1\endcsname} % @asis just yields its argument. Used with @table, for example. % \def\asis#1{#1} % @math means output in math mode. % We don't use $'s directly in the definition of \math because control % sequences like \math are expanded when the toc file is written. Then, % we read the toc file back, the $'s will be normal characters (as they % should be, according to the definition of Texinfo). So we must use a % control sequence to switch into and out of math mode. % % This isn't quite enough for @math to work properly in indices, but it % seems unlikely it will ever be needed there. % \let\implicitmath = $ \def\math#1{\implicitmath #1\implicitmath} % @bullet and @minus need the same treatment as @math, just above. \def\bullet{\implicitmath\ptexbullet\implicitmath} \def\minus{\implicitmath-\implicitmath} % @refill is a no-op. \let\refill=\relax % If working on a large document in chapters, it is convenient to % be able to disable indexing, cross-referencing, and contents, for test runs. % This is done with @novalidate (before @setfilename). % \newif\iflinks \linkstrue % by default we want the aux files. \let\novalidate = \linksfalse % @setfilename is done at the beginning of every texinfo file. % So open here the files we need to have open while reading the input. % This makes it possible to make a .fmt file for texinfo. \def\setfilename{% \iflinks \readauxfile \fi % \openindices needs to do some work in any case. \openindices \fixbackslash % Turn off hack to swallow `\input texinfo'. \global\let\setfilename=\comment % Ignore extra @setfilename cmds. % % If texinfo.cnf is present on the system, read it. % Useful for site-wide @afourpaper, etc. % Just to be on the safe side, close the input stream before the \input. \openin 1 texinfo.cnf \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi \closein1 \temp % \comment % Ignore the actual filename. } % Called from \setfilename. % \def\openindices{% \newindex{cp}% \newcodeindex{fn}% \newcodeindex{vr}% \newcodeindex{tp}% \newcodeindex{ky}% \newcodeindex{pg}% } % @bye. \outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} \message{fonts,} % Font-change commands. % Texinfo sort of supports the sans serif font style, which plain TeX does not. % So we set up a \sf analogous to plain's \rm, etc. \newfam\sffam \def\sf{\fam=\sffam \tensf} \let\li = \sf % Sometimes we call it \li, not \sf. % We don't need math for this one. \def\ttsl{\tenttsl} % Use Computer Modern fonts at \magstephalf (11pt). \newcount\mainmagstep \mainmagstep=\magstephalf % Set the font macro #1 to the font named #2, adding on the % specified font prefix (normally `cm'). % #3 is the font's design size, #4 is a scale factor \def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} % Use cm as the default font prefix. % To specify the font prefix, you must define \fontprefix % before you read in texinfo.tex. \ifx\fontprefix\undefined \def\fontprefix{cm} \fi % Support font families that don't use the same naming scheme as CM. \def\rmshape{r} \def\rmbshape{bx} %where the normal face is bold \def\bfshape{b} \def\bxshape{bx} \def\ttshape{tt} \def\ttbshape{tt} \def\ttslshape{sltt} \def\itshape{ti} \def\itbshape{bxti} \def\slshape{sl} \def\slbshape{bxsl} \def\sfshape{ss} \def\sfbshape{ss} \def\scshape{csc} \def\scbshape{csc} \ifx\bigger\relax \let\mainmagstep=\magstep1 \setfont\textrm\rmshape{12}{1000} \setfont\texttt\ttshape{12}{1000} \else \setfont\textrm\rmshape{10}{\mainmagstep} \setfont\texttt\ttshape{10}{\mainmagstep} \fi % Instead of cmb10, you many want to use cmbx10. % cmbx10 is a prettier font on its own, but cmb10 % looks better when embedded in a line with cmr10. \setfont\textbf\bfshape{10}{\mainmagstep} \setfont\textit\itshape{10}{\mainmagstep} \setfont\textsl\slshape{10}{\mainmagstep} \setfont\textsf\sfshape{10}{\mainmagstep} \setfont\textsc\scshape{10}{\mainmagstep} \setfont\textttsl\ttslshape{10}{\mainmagstep} \font\texti=cmmi10 scaled \mainmagstep \font\textsy=cmsy10 scaled \mainmagstep % A few fonts for @defun, etc. \setfont\defbf\bxshape{10}{\magstep1} %was 1314 \setfont\deftt\ttshape{10}{\magstep1} \def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} % Fonts for indices and small examples (9pt). % We actually use the slanted font rather than the italic, % because texinfo normally uses the slanted fonts for that. % Do not make many font distinctions in general in the index, since they % aren't very useful. \setfont\ninett\ttshape{9}{1000} \setfont\ninettsl\ttslshape{10}{900} \setfont\indrm\rmshape{9}{1000} \setfont\indit\itshape{9}{1000} \setfont\indsl\slshape{9}{1000} \let\indtt=\ninett \let\indttsl=\ninettsl \let\indsf=\indrm \let\indbf=\indrm \setfont\indsc\scshape{10}{900} \font\indi=cmmi9 \font\indsy=cmsy9 % Fonts for title page: \setfont\titlerm\rmbshape{12}{\magstep3} \setfont\titleit\itbshape{10}{\magstep4} \setfont\titlesl\slbshape{10}{\magstep4} \setfont\titlett\ttbshape{12}{\magstep3} \setfont\titlettsl\ttslshape{10}{\magstep4} \setfont\titlesf\sfbshape{17}{\magstep1} \let\titlebf=\titlerm \setfont\titlesc\scbshape{10}{\magstep4} \font\titlei=cmmi12 scaled \magstep3 \font\titlesy=cmsy10 scaled \magstep4 \def\authorrm{\secrm} % Chapter (and unnumbered) fonts (17.28pt). \setfont\chaprm\rmbshape{12}{\magstep2} \setfont\chapit\itbshape{10}{\magstep3} \setfont\chapsl\slbshape{10}{\magstep3} \setfont\chaptt\ttbshape{12}{\magstep2} \setfont\chapttsl\ttslshape{10}{\magstep3} \setfont\chapsf\sfbshape{17}{1000} \let\chapbf=\chaprm \setfont\chapsc\scbshape{10}{\magstep3} \font\chapi=cmmi12 scaled \magstep2 \font\chapsy=cmsy10 scaled \magstep3 % Section fonts (14.4pt). \setfont\secrm\rmbshape{12}{\magstep1} \setfont\secit\itbshape{10}{\magstep2} \setfont\secsl\slbshape{10}{\magstep2} \setfont\sectt\ttbshape{12}{\magstep1} \setfont\secttsl\ttslshape{10}{\magstep2} \setfont\secsf\sfbshape{12}{\magstep1} \let\secbf\secrm \setfont\secsc\scbshape{10}{\magstep2} \font\seci=cmmi12 scaled \magstep1 \font\secsy=cmsy10 scaled \magstep2 % \setfont\ssecrm\bxshape{10}{\magstep1} % This size an font looked bad. % \setfont\ssecit\itshape{10}{\magstep1} % The letters were too crowded. % \setfont\ssecsl\slshape{10}{\magstep1} % \setfont\ssectt\ttshape{10}{\magstep1} % \setfont\ssecsf\sfshape{10}{\magstep1} %\setfont\ssecrm\bfshape{10}{1315} % Note the use of cmb rather than cmbx. %\setfont\ssecit\itshape{10}{1315} % Also, the size is a little larger than %\setfont\ssecsl\slshape{10}{1315} % being scaled magstep1. %\setfont\ssectt\ttshape{10}{1315} %\setfont\ssecsf\sfshape{10}{1315} %\let\ssecbf=\ssecrm % Subsection fonts (13.15pt). \setfont\ssecrm\rmbshape{12}{\magstephalf} \setfont\ssecit\itbshape{10}{1315} \setfont\ssecsl\slbshape{10}{1315} \setfont\ssectt\ttbshape{12}{\magstephalf} \setfont\ssecttsl\ttslshape{10}{1315} \setfont\ssecsf\sfbshape{12}{\magstephalf} \let\ssecbf\ssecrm \setfont\ssecsc\scbshape{10}{\magstep1} \font\sseci=cmmi12 scaled \magstephalf \font\ssecsy=cmsy10 scaled 1315 % The smallcaps and symbol fonts should actually be scaled \magstep1.5, % but that is not a standard magnification. % In order for the font changes to affect most math symbols and letters, % we have to define the \textfont of the standard families. Since % texinfo doesn't allow for producing subscripts and superscripts, we % don't bother to reset \scriptfont and \scriptscriptfont (which would % also require loading a lot more fonts). % \def\resetmathfonts{% \textfont0 = \tenrm \textfont1 = \teni \textfont2 = \tensy \textfont\itfam = \tenit \textfont\slfam = \tensl \textfont\bffam = \tenbf \textfont\ttfam = \tentt \textfont\sffam = \tensf } % The font-changing commands redefine the meanings of \tenSTYLE, instead % of just \STYLE. We do this so that font changes will continue to work % in math mode, where it is the current \fam that is relevant in most % cases, not the current font. Plain TeX does \def\bf{\fam=\bffam % \tenbf}, for example. By redefining \tenbf, we obviate the need to % redefine \bf itself. \def\textfonts{% \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl \resetmathfonts} \def\titlefonts{% \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy \let\tenttsl=\titlettsl \resetmathfonts \setleading{25pt}} \def\titlefont#1{{\titlefonts\rm #1}} \def\chapfonts{% \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl \resetmathfonts \setleading{19pt}} \def\secfonts{% \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl \resetmathfonts \setleading{16pt}} \def\subsecfonts{% \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl \resetmathfonts \setleading{15pt}} \let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf? \def\indexfonts{% \let\tenrm=\indrm \let\tenit=\indit \let\tensl=\indsl \let\tenbf=\indbf \let\tentt=\indtt \let\smallcaps=\indsc \let\tensf=\indsf \let\teni=\indi \let\tensy=\indsy \let\tenttsl=\indttsl \resetmathfonts \setleading{12pt}} % Set up the default fonts, so we can use them for creating boxes. % \textfonts % Define these so they can be easily changed for other fonts. \def\angleleft{$\langle$} \def\angleright{$\rangle$} % Count depth in font-changes, for error checks \newcount\fontdepth \fontdepth=0 % Fonts for short table of contents. \setfont\shortcontrm\rmshape{12}{1000} \setfont\shortcontbf\bxshape{12}{1000} \setfont\shortcontsl\slshape{12}{1000} %% Add scribe-like font environments, plus @l for inline lisp (usually sans %% serif) and @ii for TeX italic % \smartitalic{ARG} outputs arg in italics, followed by an italic correction % unless the following character is such as not to need one. \def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else\/\fi\fi\fi} \def\smartslanted#1{{\sl #1}\futurelet\next\smartitalicx} \def\smartitalic#1{{\it #1}\futurelet\next\smartitalicx} \let\i=\smartitalic \let\var=\smartslanted \let\dfn=\smartslanted \let\emph=\smartitalic \let\cite=\smartslanted \def\b#1{{\bf #1}} \let\strong=\b % We can't just use \exhyphenpenalty, because that only has effect at % the end of a paragraph. Restore normal hyphenation at the end of the % group within which \nohyphenation is presumably called. % \def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} \def\restorehyphenation{\hyphenchar\font = `- } \def\t#1{% {\tt \rawbackslash \frenchspacing #1}% \null } \let\ttfont=\t \def\samp#1{`\tclose{#1}'\null} \setfont\smallrm\rmshape{8}{1000} \font\smallsy=cmsy9 \def\key#1{{\smallrm\textfont2=\smallsy \leavevmode\hbox{% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% \vbox{\hrule\kern-0.4pt \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% \kern-0.4pt\hrule}% \kern-.06em\raise0.4pt\hbox{\angleright}}}} % The old definition, with no lozenge: %\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} \def\ctrl #1{{\tt \rawbackslash \hat}#1} % @file, @option are the same as @samp. \let\file=\samp \let\option=\samp % @code is a modification of @t, % which makes spaces the same size as normal in the surrounding text. \def\tclose#1{% {% % Change normal interword space to be same as for the current font. \spaceskip = \fontdimen2\font % % Switch to typewriter. \tt % % But `\ ' produces the large typewriter interword space. \def\ {{\spaceskip = 0pt{} }}% % % Turn off hyphenation. \nohyphenation % \rawbackslash \frenchspacing #1% }% \null } % We *must* turn on hyphenation at `-' and `_' in \code. % Otherwise, it is too hard to avoid overfull hboxes % in the Emacs manual, the Library manual, etc. % Unfortunately, TeX uses one parameter (\hyphenchar) to control % both hyphenation at - and hyphenation within words. % We must therefore turn them both off (\tclose does that) % and arrange explicitly to hyphenate at a dash. % -- rms. { \catcode`\-=\active \catcode`\_=\active % \global\def\code{\begingroup \catcode`\-=\active \let-\codedash \catcode`\_=\active \let_\codeunder \codex } % % If we end up with any active - characters when handling the index, % just treat them as a normal -. \global\def\indexbreaks{\catcode`\-=\active \let-\realdash} } \def\realdash{-} \def\codedash{-\discretionary{}{}{}} \def\codeunder{\ifusingtt{\normalunderscore\discretionary{}{}{}}{\_}} \def\codex #1{\tclose{#1}\endgroup} %\let\exp=\tclose %Was temporary % @kbd is like @code, except that if the argument is just one @key command, % then @kbd has no effect. % @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), % `example' (@kbd uses ttsl only inside of @example and friends), % or `code' (@kbd uses normal tty font always). \def\kbdinputstyle{\parsearg\kbdinputstylexxx} \def\kbdinputstylexxx#1{% \def\arg{#1}% \ifx\arg\worddistinct \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% \else\ifx\arg\wordexample \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% \else\ifx\arg\wordcode \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% \fi\fi\fi } \def\worddistinct{distinct} \def\wordexample{example} \def\wordcode{code} % Default is kbdinputdistinct. (Too much of a hassle to call the macro, % the catcodes are wrong for parsearg to work.) \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl} \def\xkey{\key} \def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% \ifx\one\xkey\ifx\threex\three \key{#2}% \else{\tclose{\kbdfont\look}}\fi \else{\tclose{\kbdfont\look}}\fi} % For @url, @env, @command quotes seem unnecessary, so use \code. \let\url=\code \let\env=\code \let\command=\code % @uref (abbreviation for `urlref') takes an optional second argument % specifying the text to display. First (mandatory) arg is the url. % Perhaps eventually put in a hypertex \special here. % \def\uref#1{\urefxxx #1,,\finish} \def\urefxxx#1,#2,#3\finish{% \setbox0 = \hbox{\ignorespaces #2}% \ifdim\wd0 > 0pt \unhbox0\ (\code{#1})% \else \code{#1}% \fi } % rms does not like the angle brackets --karl, 17may97. % So now @email is just like @uref. %\def\email#1{\angleleft{\tt #1}\angleright} \let\email=\uref % Check if we are currently using a typewriter font. Since all the % Computer Modern typewriter fonts have zero interword stretch (and % shrink), and it is reasonable to expect all typewriter fonts to have % this property, we can check that font parameter. % \def\ifmonospace{\ifdim\fontdimen3\font=0pt } % Typeset a dimension, e.g., `in' or `pt'. The only reason for the % argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. % \def\dmn#1{\thinspace #1} \def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} % @l was never documented to mean ``switch to the Lisp font'', % and it is not used as such in any manual I can find. We need it for % Polish suppressed-l. --karl, 22sep96. %\def\l#1{{\li #1}\null} % Explicit font changes: @r, @sc, undocumented @ii. \def\r#1{{\rm #1}} % roman font \def\sc#1{{\smallcaps#1}} % smallcaps font \def\ii#1{{\it #1}} % italic font % @acronym downcases the argument and prints in smallcaps. \def\acronym#1{{\smallcaps \lowercase{#1}}} % @pounds{} is a sterling sign. \def\pounds{{\it\$}} \message{page headings,} \newskip\titlepagetopglue \titlepagetopglue = 1.5in \newskip\titlepagebottomglue \titlepagebottomglue = 2pc % First the title page. Must do @settitle before @titlepage. \newif\ifseenauthor \newif\iffinishedtitlepage % Do an implicit @contents or @shortcontents after @end titlepage if the % user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. % \newif\ifsetcontentsaftertitlepage \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue \newif\ifsetshortcontentsaftertitlepage \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue \def\shorttitlepage{\parsearg\shorttitlepagezzz} \def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% \endgroup\page\hbox{}\page} \def\titlepage{\begingroup \parindent=0pt \textfonts \let\subtitlerm=\tenrm \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% % \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}% % % Leave some space at the very top of the page. \vglue\titlepagetopglue % % Now you can print the title using @title. \def\title{\parsearg\titlezzz}% \def\titlezzz##1{\leftline{\titlefonts\rm ##1} % print a rule at the page bottom also. \finishedtitlepagefalse \vskip4pt \hrule height 4pt width \hsize \vskip4pt}% % No rule at page bottom unless we print one at the top with @title. \finishedtitlepagetrue % % Now you can put text using @subtitle. \def\subtitle{\parsearg\subtitlezzz}% \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% % % @author should come last, but may come many times. \def\author{\parsearg\authorzzz}% \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi {\authorfont \leftline{##1}}}% % % Most title ``pages'' are actually two pages long, with space % at the top of the second. We don't want the ragged left on the second. \let\oldpage = \page \def\page{% \iffinishedtitlepage\else \finishtitlepage \fi \oldpage \let\page = \oldpage \hbox{}}% % \def\page{\oldpage \hbox{}} } \def\Etitlepage{% \iffinishedtitlepage\else \finishtitlepage \fi % It is important to do the page break before ending the group, % because the headline and footline are only empty inside the group. % If we use the new definition of \page, we always get a blank page % after the title page, which we certainly don't want. \oldpage \endgroup % % If they want short, they certainly want long too. \ifsetshortcontentsaftertitlepage \shortcontents \contents \global\let\shortcontents = \relax \global\let\contents = \relax \fi % \ifsetcontentsaftertitlepage \contents \global\let\contents = \relax \global\let\shortcontents = \relax \fi % \HEADINGSon } \def\finishtitlepage{% \vskip4pt \hrule height 2pt width \hsize \vskip\titlepagebottomglue \finishedtitlepagetrue } %%% Set up page headings and footings. \let\thispage=\folio \newtoks\evenheadline % headline on even pages \newtoks\oddheadline % headline on odd pages \newtoks\evenfootline % footline on even pages \newtoks\oddfootline % footline on odd pages % Now make Tex use those variables \headline={{\textfonts\rm \ifodd\pageno \the\oddheadline \else \the\evenheadline \fi}} \footline={{\textfonts\rm \ifodd\pageno \the\oddfootline \else \the\evenfootline \fi}\HEADINGShook} \let\HEADINGShook=\relax % Commands to set those variables. % For example, this is what @headings on does % @evenheading @thistitle|@thispage|@thischapter % @oddheading @thischapter|@thispage|@thistitle % @evenfooting @thisfile|| % @oddfooting ||@thisfile \def\evenheading{\parsearg\evenheadingxxx} \def\oddheading{\parsearg\oddheadingxxx} \def\everyheading{\parsearg\everyheadingxxx} \def\evenfooting{\parsearg\evenfootingxxx} \def\oddfooting{\parsearg\oddfootingxxx} \def\everyfooting{\parsearg\everyfootingxxx} {\catcode`\@=0 % \gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} \gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% \global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} \gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% \global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}% \gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} \gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% \global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} \gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{% \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% % % Leave some space for the footline. Hopefully ok to assume % @evenfooting will not be used by itself. \global\advance\pageheight by -\baselineskip \global\advance\vsize by -\baselineskip } \gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}} % }% unbind the catcode of @. % @headings double turns headings on for double-sided printing. % @headings single turns headings on for single-sided printing. % @headings off turns them off. % @headings on same as @headings double, retained for compatibility. % @headings after turns on double-sided headings after this page. % @headings doubleafter turns on double-sided headings after this page. % @headings singleafter turns on single-sided headings after this page. % By default, they are off at the start of a document, % and turned `on' after @end titlepage. \def\headings #1 {\csname HEADINGS#1\endcsname} \def\HEADINGSoff{ \global\evenheadline={\hfil} \global\evenfootline={\hfil} \global\oddheadline={\hfil} \global\oddfootline={\hfil}} \HEADINGSoff % When we turn headings on, set the page number to 1. % For double-sided printing, put current file name in lower left corner, % chapter name on inside top of right hand pages, document % title on inside top of left hand pages, and page numbers on outside top % edge of all pages. \def\HEADINGSdouble{ \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } \let\contentsalignmacro = \chappager % For single-sided printing, chapter title goes across top left of page, % page number on top right. \def\HEADINGSsingle{ \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\thischapter\hfil\folio}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chappager } \def\HEADINGSon{\HEADINGSdouble} \def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} \let\HEADINGSdoubleafter=\HEADINGSafter \def\HEADINGSdoublex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } \def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} \def\HEADINGSsinglex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\thischapter\hfil\folio}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chappager } % Subroutines used in generating headings % Produces Day Month Year style of output. \def\today{\number\day\space \ifcase\month\or January\or February\or March\or April\or May\or June\or July\or August\or September\or October\or November\or December\fi \space\number\year} % Use this if you want the Month Day, Year style of output. %\def\today{\ifcase\month\or %January\or February\or March\or April\or May\or June\or %July\or August\or September\or October\or November\or December\fi %\space\number\day, \number\year} % @settitle line... specifies the title of the document, for headings % It generates no output of its own \def\thistitle{No Title} \def\settitle{\parsearg\settitlezzz} \def\settitlezzz #1{\gdef\thistitle{#1}} \message{tables,} % Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x). % default indentation of table text \newdimen\tableindent \tableindent=.8in % default indentation of @itemize and @enumerate text \newdimen\itemindent \itemindent=.3in % margin between end of table item and start of table text. \newdimen\itemmargin \itemmargin=.1in % used internally for \itemindent minus \itemmargin \newdimen\itemmax % Note @table, @vtable, and @vtable define @item, @itemx, etc., with % these defs. % They also define \itemindex % to index the item name in whatever manner is desired (perhaps none). \newif\ifitemxneedsnegativevskip \def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} \def\internalBitem{\smallbreak \parsearg\itemzzz} \def\internalBitemx{\itemxpar \parsearg\itemzzz} \def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} \def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} \def\internalBkitem{\smallbreak \parsearg\kitemzzz} \def\internalBkitemx{\itemxpar \parsearg\kitemzzz} \def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% \itemzzz {#1}} \def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% \itemzzz {#1}} \def\itemzzz #1{\begingroup % \advance\hsize by -\rightskip \advance\hsize by -\tableindent \setbox0=\hbox{\itemfont{#1}}% \itemindex{#1}% \nobreak % This prevents a break before @itemx. % % If the item text does not fit in the space we have, put it on a line % by itself, and do not allow a page break either before or after that % line. We do not start a paragraph here because then if the next % command is, e.g., @kindex, the whatsit would get put into the % horizontal list on a line by itself, resulting in extra blank space. \ifdim \wd0>\itemmax % % Make this a paragraph so we get the \parskip glue and wrapping, % but leave it ragged-right. \begingroup \advance\leftskip by-\tableindent \advance\hsize by\tableindent \advance\rightskip by0pt plus1fil \leavevmode\unhbox0\par \endgroup % % We're going to be starting a paragraph, but we don't want the % \parskip glue -- logically it's part of the @item we just started. \nobreak \vskip-\parskip % % Stop a page break at the \parskip glue coming up. Unfortunately % we can't prevent a possible page break at the following % \baselineskip glue. \nobreak \endgroup \itemxneedsnegativevskipfalse \else % The item text fits into the space. Start a paragraph, so that the % following text (if any) will end up on the same line. \noindent % Do this with kerns and \unhbox so that if there is a footnote in % the item text, it can migrate to the main vertical list and % eventually be printed. \nobreak\kern-\tableindent \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 \unhbox0 \nobreak\kern\dimen0 \endgroup \itemxneedsnegativevskiptrue \fi } \def\item{\errmessage{@item while not in a table}} \def\itemx{\errmessage{@itemx while not in a table}} \def\kitem{\errmessage{@kitem while not in a table}} \def\kitemx{\errmessage{@kitemx while not in a table}} \def\xitem{\errmessage{@xitem while not in a table}} \def\xitemx{\errmessage{@xitemx while not in a table}} % Contains a kludge to get @end[description] to work. \def\description{\tablez{\dontindex}{1}{}{}{}{}} % @table, @ftable, @vtable. \def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} {\obeylines\obeyspaces% \gdef\tablex #1^^M{% \tabley\dontindex#1 \endtabley}} \def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} {\obeylines\obeyspaces% \gdef\ftablex #1^^M{% \tabley\fnitemindex#1 \endtabley \def\Eftable{\endgraf\afterenvbreak\endgroup}% \let\Etable=\relax}} \def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} {\obeylines\obeyspaces% \gdef\vtablex #1^^M{% \tabley\vritemindex#1 \endtabley \def\Evtable{\endgraf\afterenvbreak\endgroup}% \let\Etable=\relax}} \def\dontindex #1{} \def\fnitemindex #1{\doind {fn}{\code{#1}}}% \def\vritemindex #1{\doind {vr}{\code{#1}}}% {\obeyspaces % \gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% \tablez{#1}{#2}{#3}{#4}{#5}{#6}}} \def\tablez #1#2#3#4#5#6{% \aboveenvbreak % \begingroup % \def\Edescription{\Etable}% Necessary kludge. \let\itemindex=#1% \ifnum 0#3>0 \advance \leftskip by #3\mil \fi % \ifnum 0#4>0 \tableindent=#4\mil \fi % \ifnum 0#5>0 \advance \rightskip by #5\mil \fi % \def\itemfont{#2}% \itemmax=\tableindent % \advance \itemmax by -\itemmargin % \advance \leftskip by \tableindent % \exdentamount=\tableindent \parindent = 0pt \parskip = \smallskipamount \ifdim \parskip=0pt \parskip=2pt \fi% \def\Etable{\endgraf\afterenvbreak\endgroup}% \let\item = \internalBitem % \let\itemx = \internalBitemx % \let\kitem = \internalBkitem % \let\kitemx = \internalBkitemx % \let\xitem = \internalBxitem % \let\xitemx = \internalBxitemx % } % This is the counter used by @enumerate, which is really @itemize \newcount \itemno \def\itemize{\parsearg\itemizezzz} \def\itemizezzz #1{% \begingroup % ended by the @end itemize \itemizey {#1}{\Eitemize} } \def\itemizey #1#2{% \aboveenvbreak % \itemmax=\itemindent % \advance \itemmax by -\itemmargin % \advance \leftskip by \itemindent % \exdentamount=\itemindent \parindent = 0pt % \parskip = \smallskipamount % \ifdim \parskip=0pt \parskip=2pt \fi% \def#2{\endgraf\afterenvbreak\endgroup}% \def\itemcontents{#1}% \let\item=\itemizeitem} % Set sfcode to normal for the chars that usually have another value. % These are `.?!:;,' \def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000 \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 } % \splitoff TOKENS\endmark defines \first to be the first token in % TOKENS, and \rest to be the remainder. % \def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% % Allow an optional argument of an uppercase letter, lowercase letter, % or number, to specify the first label in the enumerated list. No % argument is the same as `1'. % \def\enumerate{\parsearg\enumeratezzz} \def\enumeratezzz #1{\enumeratey #1 \endenumeratey} \def\enumeratey #1 #2\endenumeratey{% \begingroup % ended by the @end enumerate % % If we were given no argument, pretend we were given `1'. \def\thearg{#1}% \ifx\thearg\empty \def\thearg{1}\fi % % Detect if the argument is a single token. If so, it might be a % letter. Otherwise, the only valid thing it can be is a number. % (We will always have one token, because of the test we just made. % This is a good thing, since \splitoff doesn't work given nothing at % all -- the first parameter is undelimited.) \expandafter\splitoff\thearg\endmark \ifx\rest\empty % Only one token in the argument. It could still be anything. % A ``lowercase letter'' is one whose \lccode is nonzero. % An ``uppercase letter'' is one whose \lccode is both nonzero, and % not equal to itself. % Otherwise, we assume it's a number. % % We need the \relax at the end of the \ifnum lines to stop TeX from % continuing to look for a . % \ifnum\lccode\expandafter`\thearg=0\relax \numericenumerate % a number (we hope) \else % It's a letter. \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax \lowercaseenumerate % lowercase letter \else \uppercaseenumerate % uppercase letter \fi \fi \else % Multiple tokens in the argument. We hope it's a number. \numericenumerate \fi } % An @enumerate whose labels are integers. The starting integer is % given in \thearg. % \def\numericenumerate{% \itemno = \thearg \startenumeration{\the\itemno}% } % The starting (lowercase) letter is in \thearg. \def\lowercaseenumerate{% \itemno = \expandafter`\thearg \startenumeration{% % Be sure we're not beyond the end of the alphabet. \ifnum\itemno=0 \errmessage{No more lowercase letters in @enumerate; get a bigger alphabet}% \fi \char\lccode\itemno }% } % The starting (uppercase) letter is in \thearg. \def\uppercaseenumerate{% \itemno = \expandafter`\thearg \startenumeration{% % Be sure we're not beyond the end of the alphabet. \ifnum\itemno=0 \errmessage{No more uppercase letters in @enumerate; get a bigger alphabet} \fi \char\uccode\itemno }% } % Call itemizey, adding a period to the first argument and supplying the % common last two arguments. Also subtract one from the initial value in % \itemno, since @item increments \itemno. % \def\startenumeration#1{% \advance\itemno by -1 \itemizey{#1.}\Eenumerate\flushcr } % @alphaenumerate and @capsenumerate are abbreviations for giving an arg % to @enumerate. % \def\alphaenumerate{\enumerate{a}} \def\capsenumerate{\enumerate{A}} \def\Ealphaenumerate{\Eenumerate} \def\Ecapsenumerate{\Eenumerate} % Definition of @item while inside @itemize. \def\itemizeitem{% \advance\itemno by 1 {\let\par=\endgraf \smallbreak}% \ifhmode \errmessage{In hmode at itemizeitem}\fi {\parskip=0in \hskip 0pt \hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% \vadjust{\penalty 1200}}% \flushcr} % @multitable macros % Amy Hendrickson, 8/18/94, 3/6/96 % % @multitable ... @end multitable will make as many columns as desired. % Contents of each column will wrap at width given in preamble. Width % can be specified either with sample text given in a template line, % or in percent of \hsize, the current width of text on page. % Table can continue over pages but will only break between lines. % To make preamble: % % Either define widths of columns in terms of percent of \hsize: % @multitable @columnfractions .25 .3 .45 % @item ... % % Numbers following @columnfractions are the percent of the total % current hsize to be used for each column. You may use as many % columns as desired. % Or use a template: % @multitable {Column 1 template} {Column 2 template} {Column 3 template} % @item ... % using the widest term desired in each column. % % For those who want to use more than one line's worth of words in % the preamble, break the line within one argument and it % will parse correctly, i.e., % % @multitable {Column 1 template} {Column 2 template} {Column 3 % template} % Not: % @multitable {Column 1 template} {Column 2 template} % {Column 3 template} % Each new table line starts with @item, each subsequent new column % starts with @tab. Empty columns may be produced by supplying @tab's % with nothing between them for as many times as empty columns are needed, % ie, @tab@tab@tab will produce two empty columns. % @item, @tab, @multitable or @end multitable do not need to be on their % own lines, but it will not hurt if they are. % Sample multitable: % @multitable {Column 1 template} {Column 2 template} {Column 3 template} % @item first col stuff @tab second col stuff @tab third col % @item % first col stuff % @tab % second col stuff % @tab % third col % @item first col stuff @tab second col stuff % @tab Many paragraphs of text may be used in any column. % % They will wrap at the width determined by the template. % @item@tab@tab This will be in third column. % @end multitable % Default dimensions may be reset by user. % @multitableparskip is vertical space between paragraphs in table. % @multitableparindent is paragraph indent in table. % @multitablecolmargin is horizontal space to be left between columns. % @multitablelinespace is space to leave between table items, baseline % to baseline. % 0pt means it depends on current normal line spacing. % \newskip\multitableparskip \newskip\multitableparindent \newdimen\multitablecolspace \newskip\multitablelinespace \multitableparskip=0pt \multitableparindent=6pt \multitablecolspace=12pt \multitablelinespace=0pt % Macros used to set up halign preamble: % \let\endsetuptable\relax \def\xendsetuptable{\endsetuptable} \let\columnfractions\relax \def\xcolumnfractions{\columnfractions} \newif\ifsetpercent % #1 is the part of the @columnfraction before the decimal point, which % is presumably either 0 or the empty string (but we don't check, we % just throw it away). #2 is the decimal part, which we use as the % percent of \hsize for this column. \def\pickupwholefraction#1.#2 {% \global\advance\colcount by 1 \expandafter\xdef\csname col\the\colcount\endcsname{.#2\hsize}% \setuptable } \newcount\colcount \def\setuptable#1{% \def\firstarg{#1}% \ifx\firstarg\xendsetuptable \let\go = \relax \else \ifx\firstarg\xcolumnfractions \global\setpercenttrue \else \ifsetpercent \let\go\pickupwholefraction \else \global\advance\colcount by 1 \setbox0=\hbox{#1\unskip }% Add a normal word space as a separator; % typically that is always in the input, anyway. \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% \fi \fi \ifx\go\pickupwholefraction % Put the argument back for the \pickupwholefraction call, so % we'll always have a period there to be parsed. \def\go{\pickupwholefraction#1}% \else \let\go = \setuptable \fi% \fi \go } % multitable syntax \def\tab{&\hskip1sp\relax} % 2/2/96 % tiny skip here makes sure this column space is % maintained, even if it is never used. % @multitable ... @end multitable definitions: % \def\multitable{\parsearg\dotable} \def\dotable#1{\bgroup \vskip\parskip \let\item\crcr \tolerance=9500 \hbadness=9500 \setmultitablespacing \parskip=\multitableparskip \parindent=\multitableparindent \overfullrule=0pt \global\colcount=0 \def\Emultitable{\global\setpercentfalse\cr\egroup\egroup}% % % To parse everything between @multitable and @item: \setuptable#1 \endsetuptable % % \everycr will reset column counter, \colcount, at the end of % each line. Every column entry will cause \colcount to advance by one. % The table preamble % looks at the current \colcount to find the correct column width. \everycr{\noalign{% % % \filbreak%% keeps underfull box messages off when table breaks over pages. % Maybe so, but it also creates really weird page breaks when the table % breaks over pages. Wouldn't \vfil be better? Wait until the problem % manifests itself, so it can be fixed for real --karl. \global\colcount=0\relax}}% % % This preamble sets up a generic column definition, which will % be used as many times as user calls for columns. % \vtop will set a single line and will also let text wrap and % continue for many paragraphs if desired. \halign\bgroup&\global\advance\colcount by 1\relax \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname % % In order to keep entries from bumping into each other % we will add a \leftskip of \multitablecolspace to all columns after % the first one. % % If a template has been used, we will add \multitablecolspace % to the width of each template entry. % % If the user has set preamble in terms of percent of \hsize we will % use that dimension as the width of the column, and the \leftskip % will keep entries from bumping into each other. Table will start at % left margin and final column will justify at right margin. % % Make sure we don't inherit \rightskip from the outer environment. \rightskip=0pt \ifnum\colcount=1 % The first column will be indented with the surrounding text. \advance\hsize by\leftskip \else \ifsetpercent \else % If user has not set preamble in terms of percent of \hsize % we will advance \hsize by \multitablecolspace. \advance\hsize by \multitablecolspace \fi % In either case we will make \leftskip=\multitablecolspace: \leftskip=\multitablecolspace \fi % Ignoring space at the beginning and end avoids an occasional spurious % blank line, when TeX decides to break the line at the space before the % box from the multistrut, so the strut ends up on a line by itself. % For example: % @multitable @columnfractions .11 .89 % @item @code{#} % @tab Legal holiday which is valid in major parts of the whole country. % Is automatically provided with highlighting sequences respectively marking % characters. \noindent\ignorespaces##\unskip\multistrut}\cr } \def\setmultitablespacing{% test to see if user has set \multitablelinespace. % If so, do nothing. If not, give it an appropriate dimension based on % current baselineskip. \ifdim\multitablelinespace=0pt %% strut to put in table in case some entry doesn't have descenders, %% to keep lines equally spaced \let\multistrut = \strut %% Test to see if parskip is larger than space between lines of %% table. If not, do nothing. %% If so, set to same dimension as multitablelinespace. \else \gdef\multistrut{\vrule height\multitablelinespace depth\dp0 width0pt\relax} \fi \ifdim\multitableparskip>\multitablelinespace \global\multitableparskip=\multitablelinespace \global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller %% than skip between lines in the table. \fi% \ifdim\multitableparskip=0pt \global\multitableparskip=\multitablelinespace \global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller %% than skip between lines in the table. \fi} \message{indexing,} % Index generation facilities % Define \newwrite to be identical to plain tex's \newwrite % except not \outer, so it can be used within \newindex. {\catcode`\@=11 \gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} % \newindex {foo} defines an index named foo. % It automatically defines \fooindex such that % \fooindex ...rest of line... puts an entry in the index foo. % It also defines \fooindfile to be the number of the output channel for % the file that accumulates this index. The file's extension is foo. % The name of an index should be no more than 2 characters long % for the sake of vms. % \def\newindex#1{% \iflinks \expandafter\newwrite \csname#1indfile\endcsname \openout \csname#1indfile\endcsname \jobname.#1 % Open the file \fi \expandafter\xdef\csname#1index\endcsname{% % Define @#1index \noexpand\doindex{#1}} } % @defindex foo == \newindex{foo} \def\defindex{\parsearg\newindex} % Define @defcodeindex, like @defindex except put all entries in @code. \def\newcodeindex#1{% \iflinks \expandafter\newwrite \csname#1indfile\endcsname \openout \csname#1indfile\endcsname \jobname.#1 \fi \expandafter\xdef\csname#1index\endcsname{% \noexpand\docodeindex{#1}} } \def\defcodeindex{\parsearg\newcodeindex} % @synindex foo bar makes index foo feed into index bar. % Do this instead of @defindex foo if you don't want it as a separate index. % The \closeout helps reduce unnecessary open files; the limit on the % Acorn RISC OS is a mere 16 files. \def\synindex#1 #2 {% \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname \expandafter\closeout\csname#1indfile\endcsname \expandafter\let\csname#1indfile\endcsname=\synindexfoo \expandafter\xdef\csname#1index\endcsname{% define \xxxindex \noexpand\doindex{#2}}% } % @syncodeindex foo bar similar, but put all entries made for index foo % inside @code. \def\syncodeindex#1 #2 {% \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname \expandafter\closeout\csname#1indfile\endcsname \expandafter\let\csname#1indfile\endcsname=\synindexfoo \expandafter\xdef\csname#1index\endcsname{% define \xxxindex \noexpand\docodeindex{#2}}% } % Define \doindex, the driver for all \fooindex macros. % Argument #1 is generated by the calling \fooindex macro, % and it is "foo", the name of the index. % \doindex just uses \parsearg; it calls \doind for the actual work. % This is because \doind is more useful to call from other macros. % There is also \dosubind {index}{topic}{subtopic} % which makes an entry in a two-level index such as the operation index. \def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} \def\singleindexer #1{\doind{\indexname}{#1}} % like the previous two, but they put @code around the argument. \def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} \def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} \def\indexdummies{% \def\ { }% % Take care of the plain tex accent commands. \def\"{\realbackslash "}% \def\`{\realbackslash `}% \def\'{\realbackslash '}% \def\^{\realbackslash ^}% \def\~{\realbackslash ~}% \def\={\realbackslash =}% \def\b{\realbackslash b}% \def\c{\realbackslash c}% \def\d{\realbackslash d}% \def\u{\realbackslash u}% \def\v{\realbackslash v}% \def\H{\realbackslash H}% % Take care of the plain tex special European modified letters. \def\oe{\realbackslash oe}% \def\ae{\realbackslash ae}% \def\aa{\realbackslash aa}% \def\OE{\realbackslash OE}% \def\AE{\realbackslash AE}% \def\AA{\realbackslash AA}% \def\o{\realbackslash o}% \def\O{\realbackslash O}% \def\l{\realbackslash l}% \def\L{\realbackslash L}% \def\ss{\realbackslash ss}% % Take care of texinfo commands likely to appear in an index entry. % (Must be a way to avoid doing expansion at all, and thus not have to % laboriously list every single command here.) \def\@{@}% will be @@ when we switch to @ as escape char. % Need these in case \tex is in effect and \{ is a \delimiter again. % But can't use \lbracecmd and \rbracecmd because texindex assumes % braces and backslashes are used only as delimiters. \let\{ = \mylbrace \let\} = \myrbrace \def\_{{\realbackslash _}}% \def\w{\realbackslash w }% \def\bf{\realbackslash bf }% %\def\rm{\realbackslash rm }% \def\sl{\realbackslash sl }% \def\sf{\realbackslash sf}% \def\tt{\realbackslash tt}% \def\gtr{\realbackslash gtr}% \def\less{\realbackslash less}% \def\hat{\realbackslash hat}% \def\TeX{\realbackslash TeX}% \def\dots{\realbackslash dots }% \def\result{\realbackslash result}% \def\equiv{\realbackslash equiv}% \def\expansion{\realbackslash expansion}% \def\print{\realbackslash print}% \def\error{\realbackslash error}% \def\point{\realbackslash point}% \def\copyright{\realbackslash copyright}% \def\tclose##1{\realbackslash tclose {##1}}% \def\code##1{\realbackslash code {##1}}% \def\uref##1{\realbackslash uref {##1}}% \def\url##1{\realbackslash url {##1}}% \def\env##1{\realbackslash env {##1}}% \def\command##1{\realbackslash command {##1}}% \def\option##1{\realbackslash option {##1}}% \def\dotless##1{\realbackslash dotless {##1}}% \def\samp##1{\realbackslash samp {##1}}% \def\,##1{\realbackslash ,{##1}}% \def\t##1{\realbackslash t {##1}}% \def\r##1{\realbackslash r {##1}}% \def\i##1{\realbackslash i {##1}}% \def\b##1{\realbackslash b {##1}}% \def\sc##1{\realbackslash sc {##1}}% \def\cite##1{\realbackslash cite {##1}}% \def\key##1{\realbackslash key {##1}}% \def\file##1{\realbackslash file {##1}}% \def\var##1{\realbackslash var {##1}}% \def\kbd##1{\realbackslash kbd {##1}}% \def\dfn##1{\realbackslash dfn {##1}}% \def\emph##1{\realbackslash emph {##1}}% \def\acronym##1{\realbackslash acronym {##1}}% % % Handle some cases of @value -- where the variable name does not % contain - or _, and the value does not contain any % (non-fully-expandable) commands. \let\value = \expandablevalue % \unsepspaces } % If an index command is used in an @example environment, any spaces % therein should become regular spaces in the raw index file, not the % expansion of \tie (\\leavevmode \penalty \@M \ ). {\obeyspaces \gdef\unsepspaces{\obeyspaces\let =\space}} % \indexnofonts no-ops all font-change commands. % This is used when outputting the strings to sort the index by. \def\indexdummyfont#1{#1} \def\indexdummytex{TeX} \def\indexdummydots{...} \def\indexnofonts{% % Just ignore accents. \let\,=\indexdummyfont \let\"=\indexdummyfont \let\`=\indexdummyfont \let\'=\indexdummyfont \let\^=\indexdummyfont \let\~=\indexdummyfont \let\==\indexdummyfont \let\b=\indexdummyfont \let\c=\indexdummyfont \let\d=\indexdummyfont \let\u=\indexdummyfont \let\v=\indexdummyfont \let\H=\indexdummyfont \let\dotless=\indexdummyfont % Take care of the plain tex special European modified letters. \def\oe{oe}% \def\ae{ae}% \def\aa{aa}% \def\OE{OE}% \def\AE{AE}% \def\AA{AA}% \def\o{o}% \def\O{O}% \def\l{l}% \def\L{L}% \def\ss{ss}% \let\w=\indexdummyfont \let\t=\indexdummyfont \let\r=\indexdummyfont \let\i=\indexdummyfont \let\b=\indexdummyfont \let\emph=\indexdummyfont \let\strong=\indexdummyfont \let\cite=\indexdummyfont \let\sc=\indexdummyfont %Don't no-op \tt, since it isn't a user-level command % and is used in the definitions of the active chars like <, >, |... %\let\tt=\indexdummyfont \let\tclose=\indexdummyfont \let\code=\indexdummyfont \let\url=\indexdummyfont \let\uref=\indexdummyfont \let\env=\indexdummyfont \let\command=\indexdummyfont \let\option=\indexdummyfont \let\file=\indexdummyfont \let\samp=\indexdummyfont \let\kbd=\indexdummyfont \let\key=\indexdummyfont \let\var=\indexdummyfont \let\TeX=\indexdummytex \let\dots=\indexdummydots \def\@{@}% } % To define \realbackslash, we must make \ not be an escape. % We must first make another character (@) an escape % so we do not become unable to do a definition. {\catcode`\@=0 \catcode`\\=\other @gdef@realbackslash{\}} \let\indexbackslash=0 %overridden during \printindex. \let\SETmarginindex=\relax % put index entries in margin (undocumented)? % For \ifx comparisons. \def\emptymacro{\empty} % Most index entries go through here, but \dosubind is the general case. % \def\doind#1#2{\dosubind{#1}{#2}\empty} % Workhorse for all \fooindexes. % #1 is name of index, #2 is stuff to put there, #3 is subentry -- % \empty if called from \doind, as we usually are. The main exception % is with defuns, which call us directly. % \def\dosubind#1#2#3{% % Put the index entry in the margin if desired. \ifx\SETmarginindex\relax\else \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}% \fi {% \count255=\lastpenalty {% \indexdummies % Must do this here, since \bf, etc expand at this stage \escapechar=`\\ {% \let\folio = 0% We will expand all macros now EXCEPT \folio. \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now % so it will be output as is; and it will print as backslash. % \def\thirdarg{#3}% % % If third arg is present, precede it with space in sort key. \ifx\thirdarg\emptymacro \let\subentry = \empty \else \def\subentry{ #3}% \fi % % First process the index-string with all font commands turned off % to get the string to sort by. {\indexnofonts \xdef\indexsorttmp{#2\subentry}}% % % Now produce the complete index entry, with both the sort key and the % original text, including any font commands. \toks0 = {#2}% \edef\temp{% \write\csname#1indfile\endcsname{% \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}% }% % % If third (subentry) arg is present, add it to the index string. \ifx\thirdarg\emptymacro \else \toks0 = {#3}% \edef\temp{\temp{\the\toks0}}% \fi % % If a skip is the last thing on the list now, preserve it % by backing up by \lastskip, doing the \write, then inserting % the skip again. Otherwise, the whatsit generated by the % \write will make \lastskip zero. The result is that sequences % like this: % @end defun % @tindex whatever % @defun ... % will have extra space inserted, because the \medbreak in the % start of the @defun won't see the skip inserted by the @end of % the previous defun. % % But don't do any of this if we're not in vertical mode. We % don't want to do a \vskip and prematurely end a paragraph. % % Avoid page breaks due to these extra skips, too. % \iflinks \ifvmode \skip0 = \lastskip \ifdim\lastskip = 0pt \else \nobreak\vskip-\lastskip \fi \fi % \temp % do the write % % \ifvmode \ifdim\skip0 = 0pt \else \nobreak\vskip\skip0 \fi \fi \fi }% }% \penalty\count255 }% } % The index entry written in the file actually looks like % \entry {sortstring}{page}{topic} % or % \entry {sortstring}{page}{topic}{subtopic} % The texindex program reads in these files and writes files % containing these kinds of lines: % \initial {c} % before the first topic whose initial is c % \entry {topic}{pagelist} % for a topic that is used without subtopics % \primary {topic} % for the beginning of a topic that is used with subtopics % \secondary {subtopic}{pagelist} % for each subtopic. % Define the user-accessible indexing commands % @findex, @vindex, @kindex, @cindex. \def\findex {\fnindex} \def\kindex {\kyindex} \def\cindex {\cpindex} \def\vindex {\vrindex} \def\tindex {\tpindex} \def\pindex {\pgindex} \def\cindexsub {\begingroup\obeylines\cindexsub} {\obeylines % \gdef\cindexsub "#1" #2^^M{\endgroup % \dosubind{cp}{#2}{#1}}} % Define the macros used in formatting output of the sorted index material. % @printindex causes a particular index (the ??s file) to get printed. % It does not print any chapter heading (usually an @unnumbered). % \def\printindex{\parsearg\doprintindex} \def\doprintindex#1{\begingroup \dobreak \chapheadingskip{10000}% % \indexfonts \rm \tolerance = 9500 \indexbreaks % % See if the index file exists and is nonempty. % Change catcode of @ here so that if the index file contains % \initial {@} % as its first line, TeX doesn't complain about mismatched braces % (because it thinks @} is a control sequence). \catcode`\@ = 11 \openin 1 \jobname.#1s \ifeof 1 % \enddoublecolumns gets confused if there is no text in the index, % and it loses the chapter title and the aux file entries for the % index. The easiest way to prevent this problem is to make sure % there is some text. (Index is nonexistent) \else % % If the index file exists but is empty, then \openin leaves \ifeof % false. We have to make TeX try to read something from the file, so % it can discover if there is anything in it. \read 1 to \temp \ifeof 1 (Index is empty) \else % Index files are almost Texinfo source, but we use \ as the escape % character. It would be better to use @, but that's too big a change % to make right now. \def\indexbackslash{\rawbackslashxx}% \catcode`\\ = 0 \escapechar = `\\ \begindoublecolumns \input \jobname.#1s \enddoublecolumns \fi \fi \closein 1 \endgroup} % These macros are used by the sorted index file itself. % Change them to control the appearance of the index. \def\initial#1{{% % Some minor font changes for the special characters. \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt % % Remove any glue we may have, we'll be inserting our own. \removelastskip % % We like breaks before the index initials, so insert a bonus. \penalty -300 % % Typeset the initial. Making this add up to a whole number of % baselineskips increases the chance of the dots lining up from column % to column. It still won't often be perfect, because of the stretch % we need before each entry, but it's better. % % No shrink because it confuses \balancecolumns. \vskip 1.67\baselineskip plus .5\baselineskip \leftline{\secbf #1}% \vskip .33\baselineskip plus .1\baselineskip % % Do our best not to break after the initial. \nobreak }} % This typesets a paragraph consisting of #1, dot leaders, and then #2 % flush to the right margin. It is used for index and table of contents % entries. The paragraph is indented by \leftskip. % \def\entry#1#2{\begingroup % % Start a new paragraph if necessary, so our assignments below can't % affect previous text. \par % % Do not fill out the last line with white space. \parfillskip = 0in % % No extra space above this paragraph. \parskip = 0in % % Do not prefer a separate line ending with a hyphen to fewer lines. \finalhyphendemerits = 0 % % \hangindent is only relevant when the entry text and page number % don't both fit on one line. In that case, bob suggests starting the % dots pretty far over on the line. Unfortunately, a large % indentation looks wrong when the entry text itself is broken across % lines. So we use a small indentation and put up with long leaders. % % \hangafter is reset to 1 (which is the value we want) at the start % of each paragraph, so we need not do anything with that. \hangindent = 2em % % When the entry text needs to be broken, just fill out the first line % with blank space. \rightskip = 0pt plus1fil % % A bit of stretch before each entry for the benefit of balancing columns. \vskip 0pt plus1pt % % Start a ``paragraph'' for the index entry so the line breaking % parameters we've set above will have an effect. \noindent % % Insert the text of the index entry. TeX will do line-breaking on it. #1% % The following is kludged to not output a line of dots in the index if % there are no page numbers. The next person who breaks this will be % cursed by a Unix daemon. \def\tempa{{\rm }}% \def\tempb{#2}% \edef\tempc{\tempa}% \edef\tempd{\tempb}% \ifx\tempc\tempd\ \else% % % If we must, put the page number on a line of its own, and fill out % this line with blank space. (The \hfil is overwhelmed with the % fill leaders glue in \indexdotfill if the page number does fit.) \hfil\penalty50 \null\nobreak\indexdotfill % Have leaders before the page number. % % The `\ ' here is removed by the implicit \unskip that TeX does as % part of (the primitive) \par. Without it, a spurious underfull % \hbox ensues. \ #2% The page number ends the paragraph. \fi% \par \endgroup} % Like \dotfill except takes at least 1 em. \def\indexdotfill{\cleaders \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill} \def\primary #1{\line{#1\hfil}} \newskip\secondaryindent \secondaryindent=0.5cm \def\secondary #1#2{ {\parfillskip=0in \parskip=0in \hangindent =1in \hangafter=1 \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill #2\par }} % Define two-column mode, which we use to typeset indexes. % Adapted from the TeXbook, page 416, which is to say, % the manmac.tex format used to print the TeXbook itself. \catcode`\@=11 \newbox\partialpage \newdimen\doublecolumnhsize \def\begindoublecolumns{\begingroup % ended by \enddoublecolumns % Grab any single-column material above us. \output = {\global\setbox\partialpage = \vbox{% % % Here is a possibility not foreseen in manmac: if we accumulate a % whole lot of material, we might end up calling this \output % routine twice in a row (see the doublecol-lose test, which is % essentially a couple of indexes with @setchapternewpage off). In % that case, we must prevent the second \partialpage from % simply overwriting the first, causing us to lose the page. % This will preserve it until a real output routine can ship it % out. Generally, \partialpage will be empty when this runs and % this will be a no-op. \unvbox\partialpage % % Unvbox the main output page. \unvbox255 \kern-\topskip \kern\baselineskip }}% \eject % run that output routine to set \partialpage % % Use the double-column output routine for subsequent pages. \output = {\doublecolumnout}% % % Change the page size parameters. We could do this once outside this % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 % format, but then we repeat the same computation. Repeating a couple % of assignments once per index is clearly meaningless for the % execution time, so we may as well do it in one place. % % First we halve the line length, less a little for the gutter between % the columns. We compute the gutter based on the line length, so it % changes automatically with the paper format. The magic constant % below is chosen so that the gutter has the same value (well, +-<1pt) % as it did when we hard-coded it. % % We put the result in a separate register, \doublecolumhsize, so we % can restore it in \pagesofar, after \hsize itself has (potentially) % been clobbered. % \doublecolumnhsize = \hsize \advance\doublecolumnhsize by -.04154\hsize \divide\doublecolumnhsize by 2 \hsize = \doublecolumnhsize % % Double the \vsize as well. (We don't need a separate register here, % since nobody clobbers \vsize.) \advance\vsize by -\ht\partialpage \vsize = 2\vsize } % The double-column output routine for all double-column pages except % the last. % \def\doublecolumnout{% \splittopskip=\topskip \splitmaxdepth=\maxdepth % Get the available space for the double columns -- the normal % (undoubled) page height minus any material left over from the % previous page. \dimen@ = \vsize \divide\dimen@ by 2 % % box0 will be the left-hand column, box2 the right. \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ \onepageout\pagesofar \unvbox255 \penalty\outputpenalty } \def\pagesofar{% % Re-output the contents of the output page -- any previous material, % followed by the two boxes we just split, in box0 and box2. \advance\vsize by \ht\partialpage \unvbox\partialpage % \hsize = \doublecolumnhsize \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}% } \def\enddoublecolumns{% \output = {% % Split the last of the double-column material. Leave it on the % current page, no automatic page break. \balancecolumns % % If we end up splitting too much material for the current page, % though, there will be another page break right after this \output % invocation ends. Having called \balancecolumns once, we do not % want to call it again. Therefore, reset \output to its normal % definition right away. (We hope \balancecolumns will never be % called on to balance too much material, but if it is, this makes % the output somewhat more palatable.) \global\output = {\onepageout{\pagecontents\PAGE}}% }% \eject \endgroup % started in \begindoublecolumns % % \pagegoal was set to the doubled \vsize above, since we restarted % the current page. We're now back to normal single-column % typesetting, so reset \pagegoal to the normal \vsize (after the % \endgroup where \vsize got restored). \pagegoal = \vsize } \def\balancecolumns{% % Called at the end of the double column material. \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. \dimen@ = \ht0 \advance\dimen@ by \topskip \advance\dimen@ by-\baselineskip \divide\dimen@ by 2 % target to split to %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% \splittopskip = \topskip % Loop until we get a decent breakpoint. {% \vbadness = 10000 \loop \global\setbox3 = \copy0 \global\setbox1 = \vsplit3 to \dimen@ \ifdim\ht3>\dimen@ \global\advance\dimen@ by 1pt \repeat }% %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% \setbox0=\vbox to\dimen@{\unvbox1}% \setbox2=\vbox to\dimen@{\unvbox3}% % \pagesofar } \catcode`\@ = \other \message{sectioning,} % Define chapters, sections, etc. \newcount\chapno \newcount\secno \secno=0 \newcount\subsecno \subsecno=0 \newcount\subsubsecno \subsubsecno=0 % This counter is funny since it counts through charcodes of letters A, B, ... \newcount\appendixno \appendixno = `\@ \def\appendixletter{\char\the\appendixno} % Each @chapter defines this as the name of the chapter. % page headings and footings can use it. @section does likewise. \def\thischapter{} \def\thissection{} \newcount\absseclevel % used to calculate proper heading level \newcount\secbase\secbase=0 % @raise/lowersections modify this count % @raisesections: treat @section as chapter, @subsection as section, etc. \def\raisesections{\global\advance\secbase by -1} \let\up=\raisesections % original BFox name % @lowersections: treat @chapter as section, @section as subsection, etc. \def\lowersections{\global\advance\secbase by 1} \let\down=\lowersections % original BFox name % Choose a numbered-heading macro % #1 is heading level if unmodified by @raisesections or @lowersections % #2 is text for heading \def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \chapterzzz{#2} \or \seczzz{#2} \or \numberedsubseczzz{#2} \or \numberedsubsubseczzz{#2} \else \ifnum \absseclevel<0 \chapterzzz{#2} \else \numberedsubsubseczzz{#2} \fi \fi } % like \numhead, but chooses appendix heading levels \def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \appendixzzz{#2} \or \appendixsectionzzz{#2} \or \appendixsubseczzz{#2} \or \appendixsubsubseczzz{#2} \else \ifnum \absseclevel<0 \appendixzzz{#2} \else \appendixsubsubseczzz{#2} \fi \fi } % like \numhead, but chooses numberless heading levels \def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \unnumberedzzz{#2} \or \unnumberedseczzz{#2} \or \unnumberedsubseczzz{#2} \or \unnumberedsubsubseczzz{#2} \else \ifnum \absseclevel<0 \unnumberedzzz{#2} \else \unnumberedsubsubseczzz{#2} \fi \fi } % @chapter, @appendix, @unnumbered. \def\thischaptername{No Chapter Title} \outer\def\chapter{\parsearg\chapteryyy} \def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz \def\chapterzzz #1{% \secno=0 \subsecno=0 \subsubsecno=0 \global\advance \chapno by 1 \message{\putwordChapter\space \the\chapno}% \chapmacro {#1}{\the\chapno}% \gdef\thissection{#1}% \gdef\thischaptername{#1}% % We don't substitute the actual chapter name into \thischapter % because we don't want its macros evaluated now. \xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash chapentry{\the\toks0}% {\the\chapno}}}% \temp \donoderef \global\let\section = \numberedsec \global\let\subsection = \numberedsubsec \global\let\subsubsection = \numberedsubsubsec } \outer\def\appendix{\parsearg\appendixyyy} \def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz \def\appendixzzz #1{% \secno=0 \subsecno=0 \subsubsecno=0 \global\advance \appendixno by 1 \message{\putwordAppendix\space \appendixletter}% \chapmacro {#1}{\putwordAppendix{} \appendixletter}% \gdef\thissection{#1}% \gdef\thischaptername{#1}% \xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash chapentry{\the\toks0}% {\putwordAppendix{} \appendixletter}}}% \temp \appendixnoderef \global\let\section = \appendixsec \global\let\subsection = \appendixsubsec \global\let\subsubsection = \appendixsubsubsec } % @centerchap is like @unnumbered, but the heading is centered. \outer\def\centerchap{\parsearg\centerchapyyy} \def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}} % @top is like @unnumbered. \outer\def\top{\parsearg\unnumberedyyy} \outer\def\unnumbered{\parsearg\unnumberedyyy} \def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz \def\unnumberedzzz #1{% \secno=0 \subsecno=0 \subsubsecno=0 % % This used to be simply \message{#1}, but TeX fully expands the % argument to \message. Therefore, if #1 contained @-commands, TeX % expanded them. For example, in `@unnumbered The @cite{Book}', TeX % expanded @cite (which turns out to cause errors because \cite is meant % to be executed, not expanded). % % Anyway, we don't want the fully-expanded definition of @cite to appear % as a result of the \message, we just want `@cite' itself. We use % \the to achieve this: TeX expands \the only once, % simply yielding the contents of . (We also do this for % the toc entries.) \toks0 = {#1}\message{(\the\toks0)}% % \unnumbchapmacro {#1}% \gdef\thischapter{#1}\gdef\thissection{#1}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash unnumbchapentry{\the\toks0}}}% \temp \unnumbnoderef \global\let\section = \unnumberedsec \global\let\subsection = \unnumberedsubsec \global\let\subsubsection = \unnumberedsubsubsec } % Sections. \outer\def\numberedsec{\parsearg\secyyy} \def\secyyy #1{\numhead1{#1}} % normally calls seczzz \def\seczzz #1{% \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % \gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash secentry{\the\toks0}% {\the\chapno}{\the\secno}}}% \temp \donoderef \nobreak } \outer\def\appendixsection{\parsearg\appendixsecyyy} \outer\def\appendixsec{\parsearg\appendixsecyyy} \def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz \def\appendixsectionzzz #1{% \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % \gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash secentry{\the\toks0}% {\appendixletter}{\the\secno}}}% \temp \appendixnoderef \nobreak } \outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} \def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz \def\unnumberedseczzz #1{% \plainsecheading {#1}\gdef\thissection{#1}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash unnumbsecentry{\the\toks0}}}% \temp \unnumbnoderef \nobreak } % Subsections. \outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} \def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz \def\numberedsubseczzz #1{% \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % \subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash subsecentry{\the\toks0}% {\the\chapno}{\the\secno}{\the\subsecno}}}% \temp \donoderef \nobreak } \outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} \def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz \def\appendixsubseczzz #1{% \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % \subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash subsecentry{\the\toks0}% {\appendixletter}{\the\secno}{\the\subsecno}}}% \temp \appendixnoderef \nobreak } \outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} \def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz \def\unnumberedsubseczzz #1{% \plainsubsecheading {#1}\gdef\thissection{#1}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash unnumbsubsecentry% {\the\toks0}}}% \temp \unnumbnoderef \nobreak } % Subsubsections. \outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} \def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz \def\numberedsubsubseczzz #1{% \gdef\thissection{#1}\global\advance \subsubsecno by 1 % \subsubsecheading {#1} {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash subsubsecentry{\the\toks0}% {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}}}% \temp \donoderef \nobreak } \outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} \def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz \def\appendixsubsubseczzz #1{% \gdef\thissection{#1}\global\advance \subsubsecno by 1 % \subsubsecheading {#1} {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash subsubsecentry{\the\toks0}% {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}}}% \temp \appendixnoderef \nobreak } \outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} \def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz \def\unnumberedsubsubseczzz #1{% \plainsubsubsecheading {#1}\gdef\thissection{#1}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash unnumbsubsubsecentry% {\the\toks0}}}% \temp \unnumbnoderef \nobreak } % These are variants which are not "outer", so they can appear in @ifinfo. % Actually, they should now be obsolete; ordinary section commands should work. \def\infotop{\parsearg\unnumberedzzz} \def\infounnumbered{\parsearg\unnumberedzzz} \def\infounnumberedsec{\parsearg\unnumberedseczzz} \def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} \def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} \def\infoappendix{\parsearg\appendixzzz} \def\infoappendixsec{\parsearg\appendixseczzz} \def\infoappendixsubsec{\parsearg\appendixsubseczzz} \def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} \def\infochapter{\parsearg\chapterzzz} \def\infosection{\parsearg\sectionzzz} \def\infosubsection{\parsearg\subsectionzzz} \def\infosubsubsection{\parsearg\subsubsectionzzz} % These macros control what the section commands do, according % to what kind of chapter we are in (ordinary, appendix, or unnumbered). % Define them by default for a numbered chapter. \global\let\section = \numberedsec \global\let\subsection = \numberedsubsec \global\let\subsubsection = \numberedsubsubsec % Define @majorheading, @heading and @subheading % NOTE on use of \vbox for chapter headings, section headings, and such: % 1) We use \vbox rather than the earlier \line to permit % overlong headings to fold. % 2) \hyphenpenalty is set to 10000 because hyphenation in a % heading is obnoxious; this forbids it. % 3) Likewise, headings look best if no \parindent is used, and % if justification is not attempted. Hence \raggedright. \def\majorheading{\parsearg\majorheadingzzz} \def\majorheadingzzz #1{% {\advance\chapheadingskip by 10pt \chapbreak }% {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 200} \def\chapheading{\parsearg\chapheadingzzz} \def\chapheadingzzz #1{\chapbreak % {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 200} % @heading, @subheading, @subsubheading. \def\heading{\parsearg\plainsecheading} \def\subheading{\parsearg\plainsubsecheading} \def\subsubheading{\parsearg\plainsubsubsecheading} % These macros generate a chapter, section, etc. heading only % (including whitespace, linebreaking, etc. around it), % given all the information in convenient, parsed form. %%% Args are the skip and penalty (usually negative) \def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} \def\setchapterstyle #1 {\csname CHAPF#1\endcsname} %%% Define plain chapter starts, and page on/off switching for it % Parameter controlling skip before chapter headings (if needed) \newskip\chapheadingskip \def\chapbreak{\dobreak \chapheadingskip {-4000}} \def\chappager{\par\vfill\supereject} \def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} \def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} \def\CHAPPAGoff{% \global\let\contentsalignmacro = \chappager \global\let\pchapsepmacro=\chapbreak \global\let\pagealignmacro=\chappager} \def\CHAPPAGon{% \global\let\contentsalignmacro = \chappager \global\let\pchapsepmacro=\chappager \global\let\pagealignmacro=\chappager \global\def\HEADINGSon{\HEADINGSsingle}} \def\CHAPPAGodd{ \global\let\contentsalignmacro = \chapoddpage \global\let\pchapsepmacro=\chapoddpage \global\let\pagealignmacro=\chapoddpage \global\def\HEADINGSon{\HEADINGSdouble}} \CHAPPAGon \def\CHAPFplain{ \global\let\chapmacro=\chfplain \global\let\unnumbchapmacro=\unnchfplain \global\let\centerchapmacro=\centerchfplain} % Plain chapter opening. % #1 is the text, #2 the chapter number or empty if unnumbered. \def\chfplain#1#2{% \pchapsepmacro {% \chapfonts \rm \def\chapnum{#2}% \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}% \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright \hangindent = \wd0 \centerparametersmaybe \unhbox0 #1\par}% }% \nobreak\bigskip % no page break after a chapter title \nobreak } % Plain opening for unnumbered. \def\unnchfplain#1{\chfplain{#1}{}} % @centerchap -- centered and unnumbered. \let\centerparametersmaybe = \relax \def\centerchfplain#1{{% \def\centerparametersmaybe{% \advance\rightskip by 3\rightskip \leftskip = \rightskip \parfillskip = 0pt }% \chfplain{#1}{}% }} \CHAPFplain % The default \def\unnchfopen #1{% \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\nobreak } \def\chfopen #1#2{\chapoddpage {\chapfonts \vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% \par\penalty 5000 % } \def\centerchfopen #1{% \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt \hfill {\rm #1}\hfill}}\bigskip \par\nobreak } \def\CHAPFopen{ \global\let\chapmacro=\chfopen \global\let\unnumbchapmacro=\unnchfopen \global\let\centerchapmacro=\centerchfopen} % Section titles. \newskip\secheadingskip \def\secheadingbreak{\dobreak \secheadingskip {-1000}} \def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}} \def\plainsecheading#1{\sectionheading{sec}{}{#1}} % Subsection titles. \newskip \subsecheadingskip \def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}} \def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}} \def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}} % Subsubsection titles. \let\subsubsecheadingskip = \subsecheadingskip \let\subsubsecheadingbreak = \subsecheadingbreak \def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}} \def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}} % Print any size section title. % % #1 is the section type (sec/subsec/subsubsec), #2 is the section % number (maybe empty), #3 the text. \def\sectionheading#1#2#3{% {% \expandafter\advance\csname #1headingskip\endcsname by \parskip \csname #1headingbreak\endcsname }% {% % Switch to the right set of fonts. \csname #1fonts\endcsname \rm % % Only insert the separating space if we have a section number. \def\secnum{#2}% \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}% % \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright \hangindent = \wd0 % zero if no section number \unhbox0 #3}% }% \ifdim\parskip<10pt \nobreak\kern10pt\nobreak\kern-\parskip\fi \nobreak } \message{toc,} \newwrite\tocfile % Write an entry to the toc file, opening it if necessary. % Called from @chapter, etc. We supply {\folio} at the end of the % argument, which will end up as the last argument to the \...entry macro. % % We open the .toc file here instead of at @setfilename or any other % given time so that @contents can be put in the document anywhere. % \newif\iftocfileopened \def\writetocentry#1{% \iftocfileopened\else \immediate\openout\tocfile = \jobname.toc \global\tocfileopenedtrue \fi \iflinks \write\tocfile{#1{\folio}}\fi } \newskip\contentsrightmargin \contentsrightmargin=1in \newcount\savepageno \newcount\lastnegativepageno \lastnegativepageno = -1 % Finish up the main text and prepare to read what we've written % to \tocfile. % \def\startcontents#1{% % If @setchapternewpage on, and @headings double, the contents should % start on an odd page, unlike chapters. Thus, we maintain % \contentsalignmacro in parallel with \pagealignmacro. % From: Torbjorn Granlund \contentsalignmacro \immediate\closeout\tocfile % % Don't need to put `Contents' or `Short Contents' in the headline. % It is abundantly clear what they are. \unnumbchapmacro{#1}\def\thischapter{}% \savepageno = \pageno \begingroup % Set up to handle contents files properly. \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 % We can't do this, because then an actual ^ in a section % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97. %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi \raggedbottom % Worry more about breakpoints than the bottom. \advance\hsize by -\contentsrightmargin % Don't use the full line length. % % Roman numerals for page numbers. \ifnum \pageno>0 \pageno = \lastnegativepageno \fi } % Normal (long) toc. \def\contents{% \startcontents{\putwordTableofContents}% \openin 1 \jobname.toc \ifeof 1 \else \closein 1 \input \jobname.toc \fi \vfill \eject \endgroup \lastnegativepageno = \pageno \pageno = \savepageno } % And just the chapters. \def\summarycontents{% \startcontents{\putwordShortContents}% % \let\chapentry = \shortchapentry \let\unnumbchapentry = \shortunnumberedentry % We want a true roman here for the page numbers. \secfonts \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl \rm \hyphenpenalty = 10000 \advance\baselineskip by 1pt % Open it up a little. \def\secentry ##1##2##3##4{} \def\unnumbsecentry ##1##2{} \def\subsecentry ##1##2##3##4##5{} \def\unnumbsubsecentry ##1##2{} \def\subsubsecentry ##1##2##3##4##5##6{} \def\unnumbsubsubsecentry ##1##2{} \openin 1 \jobname.toc \ifeof 1 \else \closein 1 \input \jobname.toc \fi \vfill \eject \endgroup \lastnegativepageno = \pageno \pageno = \savepageno } \let\shortcontents = \summarycontents % These macros generate individual entries in the table of contents. % The first argument is the chapter or section name. % The last argument is the page number. % The arguments in between are the chapter number, section number, ... % Chapter-level things, for both the long and short contents. \def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}} % See comments in \dochapentry re vbox and related settings \def\shortchapentry#1#2#3{% \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno{#3}}% } % Typeset the label for a chapter or appendix for the short contents. % The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter. % We could simplify the code here by writing out an \appendixentry % command in the toc file for appendices, instead of using \chapentry % for both, but it doesn't seem worth it. \setbox0 = \hbox{\shortcontrm \putwordAppendix } \newdimen\shortappendixwidth \shortappendixwidth = \wd0 \def\shortchaplabel#1{% % We typeset #1 in a box of constant width, regardless of the text of % #1, so the chapter titles will come out aligned. \setbox0 = \hbox{#1}% \dimen0 = \ifdim\wd0 > \shortappendixwidth \shortappendixwidth \else 0pt \fi % % This space should be plenty, since a single number is .5em, and the % widest letter (M) is 1em, at least in the Computer Modern fonts. % (This space doesn't include the extra space that gets added after % the label; that gets put in by \shortchapentry above.) \advance\dimen0 by 1.1em \hbox to \dimen0{#1\hfil}% } \def\unnumbchapentry#1#2{\dochapentry{#1}{#2}} \def\shortunnumberedentry#1#2{\tocentry{#1}{\doshortpageno{#2}}} % Sections. \def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} \def\unnumbsecentry#1#2{\dosecentry{#1}{#2}} % Subsections. \def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}} \def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}} % And subsubsections. \def\subsubsecentry#1#2#3#4#5#6{% \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}} \def\unnumbsubsubsecentry#1#2{\dosubsubsecentry{#1}{#2}} % This parameter controls the indentation of the various levels. \newdimen\tocindent \tocindent = 3pc % Now for the actual typesetting. In all these, #1 is the text and #2 is the % page number. % % If the toc has to be broken over pages, we want it to be at chapters % if at all possible; hence the \penalty. \def\dochapentry#1#2{% \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip \begingroup \chapentryfonts \tocentry{#1}{\dopageno{#2}}% \endgroup \nobreak\vskip .25\baselineskip plus.1\baselineskip } \def\dosecentry#1#2{\begingroup \secentryfonts \leftskip=\tocindent \tocentry{#1}{\dopageno{#2}}% \endgroup} \def\dosubsecentry#1#2{\begingroup \subsecentryfonts \leftskip=2\tocindent \tocentry{#1}{\dopageno{#2}}% \endgroup} \def\dosubsubsecentry#1#2{\begingroup \subsubsecentryfonts \leftskip=3\tocindent \tocentry{#1}{\dopageno{#2}}% \endgroup} % Final typesetting of a toc entry; we use the same \entry macro as for % the index entries, but we want to suppress hyphenation here. (We % can't do that in the \entry macro, since index entries might consist % of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) \def\tocentry#1#2{\begingroup \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks % Do not use \turnoffactive in these arguments. Since the toc is % typeset in cmr, so characters such as _ would come out wrong; we % have to do the usual translation tricks. \entry{#1}{#2}% \endgroup} % Space between chapter (or whatever) number and the title. \def\labelspace{\hskip1em \relax} \def\dopageno#1{{\rm #1}} \def\doshortpageno#1{{\rm #1}} \def\chapentryfonts{\secfonts \rm} \def\secentryfonts{\textfonts} \let\subsecentryfonts = \textfonts \let\subsubsecentryfonts = \textfonts \message{environments,} % Since these characters are used in examples, it should be an even number of % \tt widths. Each \tt character is 1en, so two makes it 1em. % Furthermore, these definitions must come after we define our fonts. \newbox\dblarrowbox \newbox\longdblarrowbox \newbox\pushcharbox \newbox\bullbox \newbox\equivbox \newbox\errorbox %{\tentt %\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil} %\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil} %\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil} %\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil} % Adapted from the manmac format (p.420 of TeXbook) %\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex % depth .1ex\hfil} %} % @point{}, @result{}, @expansion{}, @print{}, @equiv{}. \def\point{$\star$} \def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} \def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} \def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} \def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}} % Adapted from the TeXbook's \boxit. {\tentt \global\dimen0 = 3em}% Width of the box. \dimen2 = .55pt % Thickness of rules % The text. (`r' is open on the right, `e' somewhat less so on the left.) \setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt} \global\setbox\errorbox=\hbox to \dimen0{\hfil \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. \advance\hsize by -2\dimen2 % Rules. \vbox{ \hrule height\dimen2 \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. \kern3pt\vrule width\dimen2}% Space to right. \hrule height\dimen2} \hfil} % The @error{} command. \def\error{\leavevmode\lower.7ex\copy\errorbox} % @tex ... @end tex escapes into raw Tex temporarily. % One exception: @ is still an escape character, so that @end tex works. % But \@ or @@ will get a plain tex @ character. \def\tex{\begingroup \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 \catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie \catcode `\%=14 \catcode 43=12 % plus \catcode`\"=12 \catcode`\==12 \catcode`\|=12 \catcode`\<=12 \catcode`\>=12 \escapechar=`\\ % \let\b=\ptexb \let\bullet=\ptexbullet \let\c=\ptexc \let\,=\ptexcomma \let\.=\ptexdot \let\dots=\ptexdots \let\equiv=\ptexequiv \let\!=\ptexexclam \let\i=\ptexi \let\{=\ptexlbrace \let\+=\tabalign \let\}=\ptexrbrace \let\*=\ptexstar \let\t=\ptext % \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% \def\@{@}% \let\Etex=\endgroup} % Define @lisp ... @endlisp. % @lisp does a \begingroup so it can rebind things, % including the definition of @endlisp (which normally is erroneous). % Amount to narrow the margins by for @lisp. \newskip\lispnarrowing \lispnarrowing=0.4in % This is the definition that ^^M gets inside @lisp, @example, and other % such environments. \null is better than a space, since it doesn't % have any width. \def\lisppar{\null\endgraf} % Make each space character in the input produce a normal interword % space in the output. Don't allow a line break at this space, as this % is used only in environments like @example, where each line of input % should produce a line of output anyway. % {\obeyspaces % \gdef\sepspaces{\obeyspaces\let =\tie}} % Define \obeyedspace to be our active space, whatever it is. This is % for use in \parsearg. {\sepspaces% \global\let\obeyedspace= } % This space is always present above and below environments. \newskip\envskipamount \envskipamount = 0pt % Make spacing and below environment symmetrical. We use \parskip here % to help in doing that, since in @example-like environments \parskip % is reset to zero; thus the \afterenvbreak inserts no space -- but the % start of the next paragraph will insert \parskip % \def\aboveenvbreak{{\advance\envskipamount by \parskip \endgraf \ifdim\lastskip<\envskipamount \removelastskip \penalty-50 \vskip\envskipamount \fi}} \let\afterenvbreak = \aboveenvbreak % \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. \let\nonarrowing=\relax % @cartouche ... @end cartouche: draw rectangle w/rounded corners around % environment contents. \font\circle=lcircle10 \newdimen\circthick \newdimen\cartouter\newdimen\cartinner \newskip\normbskip\newskip\normpskip\newskip\normlskip \circthick=\fontdimen8\circle % \def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth \def\ctr{{\hskip 6pt\circle\char'010}} \def\cbl{{\circle\char'012\hskip -6pt}} \def\cbr{{\hskip 6pt\circle\char'011}} \def\carttop{\hbox to \cartouter{\hskip\lskip \ctl\leaders\hrule height\circthick\hfil\ctr \hskip\rskip}} \def\cartbot{\hbox to \cartouter{\hskip\lskip \cbl\leaders\hrule height\circthick\hfil\cbr \hskip\rskip}} % \newskip\lskip\newskip\rskip \long\def\cartouche{% \begingroup \lskip=\leftskip \rskip=\rightskip \leftskip=0pt\rightskip=0pt %we want these *outside*. \cartinner=\hsize \advance\cartinner by-\lskip \advance\cartinner by-\rskip \cartouter=\hsize \advance\cartouter by 18.4pt % allow for 3pt kerns on either % side, and for 6pt waste from % each corner char, and rule thickness \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip % Flag to tell @lisp, etc., not to narrow margin. \let\nonarrowing=\comment \vbox\bgroup \baselineskip=0pt\parskip=0pt\lineskip=0pt \carttop \hbox\bgroup \hskip\lskip \vrule\kern3pt \vbox\bgroup \hsize=\cartinner \kern3pt \begingroup \baselineskip=\normbskip \lineskip=\normlskip \parskip=\normpskip \vskip -\parskip \def\Ecartouche{% \endgroup \kern3pt \egroup \kern3pt\vrule \hskip\rskip \egroup \cartbot \egroup \endgroup }} % This macro is called at the beginning of all the @example variants, % inside a group. \def\nonfillstart{% \aboveenvbreak \inENV % This group ends at the end of the body \hfuzz = 12pt % Don't be fussy \sepspaces % Make spaces be word-separators rather than space tokens. \singlespace \let\par = \lisppar % don't ignore blank lines \obeylines % each line of input is a line of output \parskip = 0pt \parindent = 0pt \emergencystretch = 0pt % don't try to avoid overfull boxes % @cartouche defines \nonarrowing to inhibit narrowing % at next level down. \ifx\nonarrowing\relax \advance \leftskip by \lispnarrowing \exdentamount=\lispnarrowing \let\exdent=\nofillexdent \let\nonarrowing=\relax \fi } % Define the \E... control sequence only if we are inside the particular % environment, so the error checking in \end will work. % % To end an @example-like environment, we first end the paragraph (via % \afterenvbreak's vertical glue), and then the group. That way we keep % the zero \parskip that the environments set -- \parskip glue will be % inserted at the beginning of the next paragraph in the document, after % the environment. % \def\nonfillfinish{\afterenvbreak\endgroup} % @lisp: indented, narrowed, typewriter font. \def\lisp{\begingroup \nonfillstart \let\Elisp = \nonfillfinish \tt \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. \gobble % eat return } % @example: Same as @lisp. \def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} % @small... is usually equivalent to the non-small (@smallbook % redefines). We must call \example (or whatever) last in the % definition, since it reads the return following the @example (or % whatever) command. % % This actually allows (for example) @end display inside an % @smalldisplay. Too bad, but makeinfo will catch the error anyway. % \def\smalldisplay{\begingroup\def\Esmalldisplay{\nonfillfinish\endgroup}\display} \def\smallexample{\begingroup\def\Esmallexample{\nonfillfinish\endgroup}\lisp} \def\smallformat{\begingroup\def\Esmallformat{\nonfillfinish\endgroup}\format} \def\smalllisp{\begingroup\def\Esmalllisp{\nonfillfinish\endgroup}\lisp} % Real @smallexample and @smalllisp (when @smallbook): use smaller fonts. % Originally contributed by Pavel@xerox. \def\smalllispx{\begingroup \def\Esmalllisp{\nonfillfinish\endgroup}% \def\Esmallexample{\nonfillfinish\endgroup}% \indexfonts \lisp } % @display: same as @lisp except keep current font. % \def\display{\begingroup \nonfillstart \let\Edisplay = \nonfillfinish \gobble } % @smalldisplay (when @smallbook): @display plus smaller fonts. % \def\smalldisplayx{\begingroup \def\Esmalldisplay{\nonfillfinish\endgroup}% \indexfonts \rm \display } % @format: same as @display except don't narrow margins. % \def\format{\begingroup \let\nonarrowing = t \nonfillstart \let\Eformat = \nonfillfinish \gobble } % @smallformat (when @smallbook): @format plus smaller fonts. % \def\smallformatx{\begingroup \def\Esmallformat{\nonfillfinish\endgroup}% \indexfonts \rm \format } % @flushleft (same as @format). % \def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format} % @flushright. % \def\flushright{\begingroup \let\nonarrowing = t \nonfillstart \let\Eflushright = \nonfillfinish \advance\leftskip by 0pt plus 1fill \gobble } % @quotation does normal linebreaking (hence we can't use \nonfillstart) % and narrows the margins. % \def\quotation{% \begingroup\inENV %This group ends at the end of the @quotation body {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip \singlespace \parindent=0pt % We have retained a nonzero parskip for the environment, since we're % doing normal filling. So to avoid extra space below the environment... \def\Equotation{\parskip = 0pt \nonfillfinish}% % % @cartouche defines \nonarrowing to inhibit narrowing at next level down. \ifx\nonarrowing\relax \advance\leftskip by \lispnarrowing \advance\rightskip by \lispnarrowing \exdentamount = \lispnarrowing \let\nonarrowing = \relax \fi } \message{defuns,} % Define formatter for defuns % First, allow user to change definition object font (\df) internally \def\setdeffont #1 {\csname DEF#1\endcsname} \newskip\defbodyindent \defbodyindent=.4in \newskip\defargsindent \defargsindent=50pt \newskip\deftypemargin \deftypemargin=12pt \newskip\deflastargmargin \deflastargmargin=18pt \newcount\parencount % define \functionparens, which makes ( and ) and & do special things. % \functionparens affects the group it is contained in. \def\activeparens{% \catcode`\(=\active \catcode`\)=\active \catcode`\&=\active \catcode`\[=\active \catcode`\]=\active} % Make control sequences which act like normal parenthesis chars. \let\lparen = ( \let\rparen = ) {\activeparens % Now, smart parens don't turn on until &foo (see \amprm) % Be sure that we always have a definition for `(', etc. For example, % if the fn name has parens in it, \boldbrax will not be in effect yet, % so TeX would otherwise complain about undefined control sequence. \global\let(=\lparen \global\let)=\rparen \global\let[=\lbrack \global\let]=\rbrack \gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} % This is used to turn on special parens % but make & act ordinary (given that it's active). \gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} % Definitions of (, ) and & used in args for functions. % This is the definition of ( outside of all parentheses. \gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested \global\advance\parencount by 1 } % % This is the definition of ( when already inside a level of parens. \gdef\opnested{\char`\(\global\advance\parencount by 1 } % \gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. % also in that case restore the outer-level definition of (. \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi \global\advance \parencount by -1 } % If we encounter &foo, then turn on ()-hacking afterwards \gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ } % \gdef\normalparens{\boldbrax\let&=\ampnr} } % End of definition inside \activeparens %% These parens (in \boldbrax) actually are a little bolder than the %% contained text. This is especially needed for [ and ] \def\opnr{{\sf\char`\(}\global\advance\parencount by 1 } \def\clnr{{\sf\char`\)}\global\advance\parencount by -1 } \def\ampnr{\&} \def\lbrb{{\bf\char`\[}} \def\rbrb{{\bf\char`\]}} % First, defname, which formats the header line itself. % #1 should be the function name. % #2 should be the type of definition, such as "Function". \def\defname #1#2{% % Get the values of \leftskip and \rightskip as they were % outside the @def... \dimen2=\leftskip \advance\dimen2 by -\defbodyindent \noindent \setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}% \dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line \dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations \parshape 2 0in \dimen0 \defargsindent \dimen1 % Now output arg 2 ("Function" or some such) % ending at \deftypemargin from the right margin, % but stuck inside a box of width 0 so it does not interfere with linebreaking {% Adjust \hsize to exclude the ambient margins, % so that \rightline will obey them. \advance \hsize by -\dimen2 \rlap{\rightline{{\rm #2}\hskip -1.25pc }}}% % Make all lines underfull and no complaints: \tolerance=10000 \hbadness=10000 \advance\leftskip by -\defbodyindent \exdentamount=\defbodyindent {\df #1}\enskip % Generate function name } % Actually process the body of a definition % #1 should be the terminating control sequence, such as \Edefun. % #2 should be the "another name" control sequence, such as \defunx. % #3 should be the control sequence that actually processes the header, % such as \defunheader. \def\defparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2{\begingroup\obeylines\activeparens\spacesplit#3}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup % \catcode 61=\active % 61 is `=' \obeylines\activeparens\spacesplit#3} % #1 is the \E... control sequence to end the definition (which we define). % #2 is the \...x control sequence for consecutive fns (which we define). % #3 is the control sequence to call to resume processing. % #4, delimited by the space, is the class name. % \def\defmethparsebody#1#2#3#4 {\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\activeparens\spacesplit{#3{#4}}} % @deftypemethod has an extra argument that nothing else does. Sigh. % #1 is the \E... control sequence to end the definition (which we define). % #2 is the \...x control sequence for consecutive fns (which we define). % #3 is the control sequence to call to resume processing. % #4, delimited by the space, is the class name. % #5 is the method's return type. % \def\deftypemethparsebody#1#2#3#4 #5 {\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 ##2 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}{##2}}}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\activeparens\spacesplit{#3{#4}{#5}}} \def\defopparsebody #1#2#3#4#5 {\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 ##2 {\def#4{##1}% \begingroup\obeylines\activeparens\spacesplit{#3{##2}}}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\activeparens\spacesplit{#3{#5}}} % These parsing functions are similar to the preceding ones % except that they do not make parens into active characters. % These are used for "variables" since they have no arguments. \def\defvarparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2{\begingroup\obeylines\spacesplit#3}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup % \catcode 61=\active % \obeylines\spacesplit#3} % This is used for \def{tp,vr}parsebody. It could probably be used for % some of the others, too, with some judicious conditionals. % \def\parsebodycommon#1#2#3{% \begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines } \def\defvrparsebody#1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \spacesplit{#3{#4}}% } % This loses on `@deftp {Data Type} {struct termios}' -- it thinks the % type is just `struct', because we lose the braces in `{struct % termios}' when \spacesplit reads its undelimited argument. Sigh. % \let\deftpparsebody=\defvrparsebody % % So, to get around this, we put \empty in with the type name. That % way, TeX won't find exactly `{...}' as an undelimited argument, and % won't strip off the braces. % \def\deftpparsebody #1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \spacesplit{\parsetpheaderline{#3{#4}}}\empty } % Fine, but then we have to eventually remove the \empty *and* the % braces (if any). That's what this does. % \def\removeemptybraces\empty#1\relax{#1} % After \spacesplit has done its work, this is called -- #1 is the final % thing to call, #2 the type name (which starts with \empty), and #3 % (which might be empty) the arguments. % \def\parsetpheaderline#1#2#3{% #1{\removeemptybraces#2\relax}{#3}% }% \def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 ##2 {\def#4{##1}% \begingroup\obeylines\spacesplit{#3{##2}}}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\spacesplit{#3{#5}}} % Split up #2 at the first space token. % call #1 with two arguments: % the first is all of #2 before the space token, % the second is all of #2 after that space token. % If #2 contains no space token, all of it is passed as the first arg % and the second is passed as empty. {\obeylines \gdef\spacesplit#1#2^^M{\endgroup\spacesplitfoo{#1}#2 \relax\spacesplitfoo}% \long\gdef\spacesplitfoo#1#2 #3#4\spacesplitfoo{% \ifx\relax #3% #1{#2}{}\else #1{#2}{#3#4}\fi}} % So much for the things common to all kinds of definitions. % Define @defun. % First, define the processing that is wanted for arguments of \defun % Use this to expand the args and terminate the paragraph they make up \def\defunargs #1{\functionparens \sl % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. \hyphenchar\tensl=0 #1% \hyphenchar\tensl=45 \ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi% \interlinepenalty=10000 \advance\rightskip by 0pt plus 1fil \endgraf\nobreak\vskip -\parskip\nobreak } \def\deftypefunargs #1{% % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. % Use \boldbraxnoamp, not \functionparens, so that & is not special. \boldbraxnoamp \tclose{#1}% avoid \code because of side effects on active chars \interlinepenalty=10000 \advance\rightskip by 0pt plus 1fil \endgraf\nobreak\vskip -\parskip\nobreak } % Do complete processing of one @defun or @defunx line already parsed. % @deffn Command forward-char nchars \def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} \def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% \begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defun == @deffn Function \def\defun{\defparsebody\Edefun\defunx\defunheader} \def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{Function}% \defunargs {#2}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @deftypefun int foobar (int @var{foo}, float @var{bar}) \def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} % #1 is the data type. #2 is the name and args. \def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} % #1 is the data type, #2 the name, #3 the args. \def\deftypefunheaderx #1#2 #3\relax{% \doind {fn}{\code{#2}}% Make entry in function index \begingroup\defname {\defheaderxcond#1\relax$$$#2}{Function}% \deftypefunargs {#3}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) \def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} % \defheaderxcond#1\relax$$$ % puts #1 in @code, followed by a space, but does nothing if #1 is null. \def\defheaderxcond#1#2$$${\ifx#1\relax\else\code{#1#2} \fi} % #1 is the classification. #2 is the data type. #3 is the name and args. \def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} % #1 is the classification, #2 the data type, #3 the name, #4 the args. \def\deftypefnheaderx #1#2#3 #4\relax{% \doind {fn}{\code{#3}}% Make entry in function index \begingroup \normalparens % notably, turn off `&' magic, which prevents % at least some C++ text from working \defname {\defheaderxcond#2\relax$$$#3}{#1}% \deftypefunargs {#4}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defmac == @deffn Macro \def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} \def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{Macro}% \defunargs {#2}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defspec == @deffn Special Form \def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} \def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{Special Form}% \defunargs {#2}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % This definition is run if you use @defunx % anywhere other than immediately after a @defun or @defunx. \def\deffnx #1 {\errmessage{@deffnx in invalid context}} \def\defunx #1 {\errmessage{@defunx in invalid context}} \def\defmacx #1 {\errmessage{@defmacx in invalid context}} \def\defspecx #1 {\errmessage{@defspecx in invalid context}} \def\deftypefnx #1 {\errmessage{@deftypefnx in invalid context}} \def\deftypemethodx #1 {\errmessage{@deftypemethodx in invalid context}} \def\deftypefunx #1 {\errmessage{@deftypefunx in invalid context}} % @defmethod, and so on % @defop CATEGORY CLASS OPERATION ARG... \def\defop #1 {\def\defoptype{#1}% \defopparsebody\Edefop\defopx\defopheader\defoptype} \def\defopheader #1#2#3{% \dosubind {fn}{\code{#2}}{\putwordon\ #1}% Make entry in function index \begingroup\defname {#2}{\defoptype{} on #1}% \defunargs {#3}\endgroup % } % @deftypemethod CLASS RETURN-TYPE METHOD ARG... % \def\deftypemethod{% \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader} % % #1 is the class name, #2 the data type, #3 the method name, #4 the args. \def\deftypemethodheader#1#2#3#4{% \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{\defheaderxcond#2\relax$$$#3}{\putwordMethodon\ \code{#1}}% \deftypefunargs{#4}% \endgroup } % @defmethod == @defop Method % \def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} % % #1 is the class name, #2 the method name, #3 the args. \def\defmethodheader#1#2#3{% \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{#2}{\putwordMethodon\ \code{#1}}% \defunargs{#3}% \endgroup } % @defcv {Class Option} foo-class foo-flag \def\defcv #1 {\def\defcvtype{#1}% \defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} \def\defcvarheader #1#2#3{% \dosubind {vr}{\code{#2}}{of #1}% Make entry in var index \begingroup\defname {#2}{\defcvtype{} of #1}% \defvarargs {#3}\endgroup % } % @defivar == @defcv {Instance Variable} \def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} \def\defivarheader #1#2#3{% \dosubind {vr}{\code{#2}}{of #1}% Make entry in var index \begingroup\defname {#2}{Instance Variable of #1}% \defvarargs {#3}\endgroup % } % These definitions are run if you use @defmethodx, etc., % anywhere other than immediately after a @defmethod, etc. \def\defopx #1 {\errmessage{@defopx in invalid context}} \def\defmethodx #1 {\errmessage{@defmethodx in invalid context}} \def\defcvx #1 {\errmessage{@defcvx in invalid context}} \def\defivarx #1 {\errmessage{@defivarx in invalid context}} % Now @defvar % First, define the processing that is wanted for arguments of @defvar. % This is actually simple: just print them in roman. % This must expand the args and terminate the paragraph they make up \def\defvarargs #1{\normalparens #1% \interlinepenalty=10000 \endgraf\nobreak\vskip -\parskip\nobreak} % @defvr Counter foo-count \def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} \def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% \begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} % @defvar == @defvr Variable \def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} \def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index \begingroup\defname {#1}{Variable}% \defvarargs {#2}\endgroup % } % @defopt == @defvr {User Option} \def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} \def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index \begingroup\defname {#1}{User Option}% \defvarargs {#2}\endgroup % } % @deftypevar int foobar \def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} % #1 is the data type. #2 is the name, perhaps followed by text that % is actually part of the data type, which should not be put into the index. \def\deftypevarheader #1#2{% \dovarind#2 \relax% Make entry in variables index \begingroup\defname {\defheaderxcond#1\relax$$$#2}{Variable}% \interlinepenalty=10000 \endgraf\nobreak\vskip -\parskip\nobreak \endgroup} \def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}} % @deftypevr {Global Flag} int enable \def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} \def\deftypevrheader #1#2#3{\dovarind#3 \relax% \begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1} \interlinepenalty=10000 \endgraf\nobreak\vskip -\parskip\nobreak \endgroup} % This definition is run if you use @defvarx % anywhere other than immediately after a @defvar or @defvarx. \def\defvrx #1 {\errmessage{@defvrx in invalid context}} \def\defvarx #1 {\errmessage{@defvarx in invalid context}} \def\defoptx #1 {\errmessage{@defoptx in invalid context}} \def\deftypevarx #1 {\errmessage{@deftypevarx in invalid context}} \def\deftypevrx #1 {\errmessage{@deftypevrx in invalid context}} % Now define @deftp % Args are printed in bold, a slight difference from @defvar. \def\deftpargs #1{\bf \defvarargs{#1}} % @deftp Class window height width ... \def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} \def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% \begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} % This definition is run if you use @deftpx, etc % anywhere other than immediately after a @deftp, etc. \def\deftpx #1 {\errmessage{@deftpx in invalid context}} \message{macros,} % @macro. % To do this right we need a feature of e-TeX, \scantokens, % which we arrange to emulate with a temporary file in ordinary TeX. \ifx\eTeXversion\undefined \newwrite\macscribble \def\scanmacro#1{% \begingroup \newlinechar`\^^M \immediate\openout\macscribble=\jobname.tmp \immediate\write\macscribble{#1}% \immediate\closeout\macscribble \let\xeatspaces\eatspaces \input \jobname.tmp \endgroup } \else \def\scanmacro#1{% \begingroup \newlinechar`\^^M \let\xeatspaces\eatspaces\scantokens{#1}\endgroup} \fi \newcount\paramno % Count of parameters \newtoks\macname % Macro name \newif\ifrecursive % Is it recursive? % Utility routines. % Thisdoes \let #1 = #2, except with \csnames. \def\cslet#1#2{% \expandafter\expandafter \expandafter\let \expandafter\expandafter \csname#1\endcsname \csname#2\endcsname} % Trim leading and trailing spaces off a string. % Concepts from aro-bend problem 15 (see CTAN). {\catcode`\@=11 \gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} \gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} \gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} \def\unbrace#1{#1} \unbrace{\gdef\trim@@@ #1 } #2@{#1} } % Trim a single trailing ^^M off a string. {\catcode`\^^M=12\catcode`\Q=3% \gdef\eatcr #1{\eatcra #1Q^^MQ}% \gdef\eatcra#1^^MQ{\eatcrb#1Q}% \gdef\eatcrb#1Q#2Q{#1}% } % Macro bodies are absorbed as an argument in a context where % all characters are catcode 10, 11 or 12, except \ which is active % (as in normal texinfo). It is necessary to change the definition of \. % It's necessary to have hard CRs when the macro is executed. This is % done by making ^^M (\endlinechar) catcode 12 when reading the macro % body, and then making it the \newlinechar in \scanmacro. \def\macrobodyctxt{% \catcode`\~=12 \catcode`\^=12 \catcode`\_=12 \catcode`\|=12 \catcode`\<=12 \catcode`\>=12 \catcode`\+=12 \catcode`\{=12 \catcode`\}=12 \catcode`\@=12 \catcode`\^^M=12 \usembodybackslash} \def\macroargctxt{% \catcode`\~=12 \catcode`\^=12 \catcode`\_=12 \catcode`\|=12 \catcode`\<=12 \catcode`\>=12 \catcode`\+=12 \catcode`\@=12 \catcode`\\=12} % \mbodybackslash is the definition of \ in @macro bodies. % It maps \foo\ => \csname macarg.foo\endcsname => #N % where N is the macro parameter number. % We define \csname macarg.\endcsname to be \realbackslash, so % \\ in macro replacement text gets you a backslash. {\catcode`@=0 @catcode`@\=@active @gdef@usembodybackslash{@let\=@mbodybackslash} @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} } \expandafter\def\csname macarg.\endcsname{\realbackslash} \def\macro{\recursivefalse\parsearg\macroxxx} \def\rmacro{\recursivetrue\parsearg\macroxxx} \def\macroxxx#1{% \getargs{#1}% now \macname is the macname and \argl the arglist \ifx\argl\empty % no arguments \paramno=0% \else \expandafter\parsemargdef \argl;% \fi \expandafter\ifx \csname macsave.\the\macname\endcsname \relax \cslet{macsave.\the\macname}{\the\macname}% \else \message{Warning: redefining \the\macname}% \fi \begingroup \macrobodyctxt \ifrecursive \expandafter\parsermacbody \else \expandafter\parsemacbody \fi} \def\unmacro{\parsearg\unmacroxxx} \def\unmacroxxx#1{% \expandafter\ifx \csname macsave.\the\macname\endcsname \relax \errmessage{Macro \the\macname\ not defined.}% \else \cslet{#1}{macsave.#1}% \expandafter\let \csname macsave.\the\macname\endcsname \undefined \fi } % This makes use of the obscure feature that if the last token of a % is #, then the preceding argument is delimited by % an opening brace, and that opening brace is not consumed. \def\getargs#1{\getargsxxx#1{}} \def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} \def\getmacname #1 #2\relax{\macname={#1}} \def\getmacargs#1{\def\argl{#1}} % Parse the optional {params} list. Set up \paramno and \paramlist % so \defmacro knows what to do. Define \macarg.blah for each blah % in the params list, to be ##N where N is the position in that list. % That gets used by \mbodybackslash (above). % We need to get `macro parameter char #' into several definitions. % The technique used is stolen from LaTeX: let \hash be something % unexpandable, insert that wherever you need a #, and then redefine % it to # just before using the token list produced. % % The same technique is used to protect \eatspaces till just before % the macro is used. \def\parsemargdef#1;{\paramno=0\def\paramlist{}% \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} \def\parsemargdefxxx#1,{% \if#1;\let\next=\relax \else \let\next=\parsemargdefxxx \advance\paramno by 1% \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname {\xeatspaces{\hash\the\paramno}}% \edef\paramlist{\paramlist\hash\the\paramno,}% \fi\next} % These two commands read recursive and nonrecursive macro bodies. % (They're different since rec and nonrec macros end differently.) \long\def\parsemacbody#1@end macro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% \long\def\parsermacbody#1@end rmacro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% % This defines the macro itself. There are six cases: recursive and % nonrecursive macros of zero, one, and many arguments. % Much magic with \expandafter here. % \xdef is used so that macro definitions will survive the file % they're defined in; @include reads the file inside a group. \def\defmacro{% \let\hash=##% convert placeholders to macro parameter chars \ifrecursive \ifcase\paramno % 0 \expandafter\xdef\csname\the\macname\endcsname{% \noexpand\scanmacro{\temp}}% \or % 1 \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \noexpand\braceorline\csname\the\macname xxx\endcsname}% \expandafter\xdef\csname\the\macname xxx\endcsname##1{% \egroup\noexpand\scanmacro{\temp}}% \else % many \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \noexpand\csname\the\macname xx\endcsname} \expandafter\xdef\csname\the\macname xx\endcsname##1{% \csname\the\macname xxx\endcsname ##1,}% \expandafter\expandafter \expandafter\xdef \expandafter\expandafter \csname\the\macname xxx\endcsname \paramlist{\egroup\noexpand\scanmacro{\temp}}% \fi \else \ifcase\paramno % 0 \expandafter\xdef\csname\the\macname\endcsname{% \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% \or % 1 \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \noexpand\braceorline\csname\the\macname xxx\endcsname}% \expandafter\xdef\csname\the\macname xxx\endcsname##1{% \egroup \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% \else % many \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \noexpand\csname\the\macname xx\endcsname} \expandafter\xdef\csname\the\macname xx\endcsname##1{% \csname\the\macname xxx\endcsname ##1,}% \expandafter\expandafter \expandafter\xdef \expandafter\expandafter \csname\the\macname xxx\endcsname \paramlist{% \egroup \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% \fi \fi} \def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} % \braceorline decides whether the next nonwhitespace character is a % {. If so it reads up to the closing }, if not, it reads the whole % line. Whatever was read is then fed to the next control sequence % as an argument (by \parsebrace or \parsearg) \def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx} \def\braceorlinexxx{% \ifx\nchar\bgroup\else \expandafter\parsearg \fi \next} \message{cross references,} \newwrite\auxfile \newif\ifhavexrefs % True if xref values are known. \newif\ifwarnedxrefs % True if we warned once that they aren't known. % @inforef is relatively simple. \def\inforef #1{\inforefzzz #1,,,,**} \def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, node \samp{\ignorespaces#1{}}} % @node's job is to define \lastnode. \def\node{\ENVcheck\parsearg\nodezzz} \def\nodezzz#1{\nodexxx [#1,]} \def\nodexxx[#1,#2]{\gdef\lastnode{#1}} \let\nwnode=\node \let\lastnode=\relax % The sectioning commands (@chapter, etc.) call these. \def\donoderef{% \ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}% {Ysectionnumberandtype}% \global\let\lastnode=\relax \fi } \def\unnumbnoderef{% \ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}{Ynothing}% \global\let\lastnode=\relax \fi } \def\appendixnoderef{% \ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}% {Yappendixletterandtype}% \global\let\lastnode=\relax \fi } % @anchor{NAME} -- define xref target at arbitrary point. % \def\anchor#1{\setref{#1}{Ynothing}} % \setref{NAME}{SNT} defines a cross-reference point NAME, namely % NAME-title, NAME-pg, and NAME-SNT. Called from \foonoderef. We have % to set \indexdummies so commands such as @code in a section title % aren't expanded. It would be nicer not to expand the titles in the % first place, but there's so many layers that that is hard to do. % \def\setref#1#2{{% \indexdummies \dosetq{#1-title}{Ytitle}% \dosetq{#1-pg}{Ypagenumber}% \dosetq{#1-snt}{#2} }} % @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is % the node name, #2 the name of the Info cross-reference, #3 the printed % node name, #4 the name of the Info file, #5 the name of the printed % manual. All but the node name can be omitted. % \def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} \def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} \def\ref#1{\xrefX[#1,,,,,,,]} \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup \def\printedmanual{\ignorespaces #5}% \def\printednodename{\ignorespaces #3}% \setbox1=\hbox{\printedmanual}% \setbox0=\hbox{\printednodename}% \ifdim \wd0 = 0pt % No printed node name was explicitly given. \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax % Use the node name inside the square brackets. \def\printednodename{\ignorespaces #1}% \else % Use the actual chapter/section title appear inside % the square brackets. Use the real section title if we have it. \ifdim \wd1 > 0pt % It is in another manual, so we don't have it. \def\printednodename{\ignorespaces #1}% \else \ifhavexrefs % We know the real title if we have the xref values. \def\printednodename{\refx{#1-title}{}}% \else % Otherwise just copy the Info node name. \def\printednodename{\ignorespaces #1}% \fi% \fi \fi \fi % % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not % insert empty discretionaries after hyphens, which means that it will % not find a line break at a hyphen in a node names. Since some manuals % are best written with fairly long node names, containing hyphens, this % is a loss. Therefore, we give the text of the node name again, so it % is as if TeX is seeing it for the first time. \ifdim \wd1 > 0pt \putwordsection{} ``\printednodename'' in \cite{\printedmanual}% \else % _ (for example) has to be the character _ for the purposes of the % control sequence corresponding to the node, but it has to expand % into the usual \leavevmode...\vrule stuff for purposes of % printing. So we \turnoffactive for the \refx-snt, back on for the % printing, back off for the \refx-pg. {\normalturnoffactive % Only output a following space if the -snt ref is nonempty; for % @unnumbered and @anchor, it won't be. \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi }% % [mynode], [\printednodename],\space % page 3 \turnoffactive \putwordpage\tie\refx{#1-pg}{}% \fi \endgroup} % \dosetq is the interface for calls from other macros % Use \normalturnoffactive so that punctuation chars such as underscore % and backslash work in node names. (\turnoffactive doesn't do \.) \def\dosetq#1#2{% {\let\folio=0 \normalturnoffactive \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}% \iflinks \next \fi }% } % \internalsetq {foo}{page} expands into % CHARACTERS 'xrdef {foo}{...expansion of \Ypage...} % When the aux file is read, ' is the escape character \def\internalsetq #1#2{'xrdef {#1}{\csname #2\endcsname}} % Things to be expanded by \internalsetq \def\Ypagenumber{\folio} \def\Ytitle{\thissection} \def\Ynothing{} \def\Ysectionnumberandtype{% \ifnum\secno=0 \putwordChapter\xreftie\the\chapno % \else \ifnum \subsecno=0 \putwordSection\xreftie\the\chapno.\the\secno % \else \ifnum \subsubsecno=0 % \putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno % \else % \putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno % \fi \fi \fi } \def\Yappendixletterandtype{% \ifnum\secno=0 \putwordAppendix\xreftie'char\the\appendixno{}% \else \ifnum \subsecno=0 \putwordSection\xreftie'char\the\appendixno.\the\secno % \else \ifnum \subsubsecno=0 % \putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno % \else % \putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % \fi \fi \fi } \gdef\xreftie{'tie} % Use TeX 3.0's \inputlineno to get the line number, for better error % messages, but if we're using an old version of TeX, don't do anything. % \ifx\inputlineno\thisisundefined \let\linenumber = \empty % Non-3.0. \else \def\linenumber{\the\inputlineno:\space} \fi % Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. % If its value is nonempty, SUFFIX is output afterward. \def\refx#1#2{% \expandafter\ifx\csname X#1\endcsname\relax % If not defined, say something at least. \angleleft un\-de\-fined\angleright \iflinks \ifhavexrefs \message{\linenumber Undefined cross reference `#1'.}% \else \ifwarnedxrefs\else \global\warnedxrefstrue \message{Cross reference values unknown; you must run TeX again.}% \fi \fi \fi \else % It's defined, so just use it. \csname X#1\endcsname \fi #2% Output the suffix in any case. } % This is the macro invoked by entries in the aux file. % \def\xrdef#1{\begingroup % Reenable \ as an escape while reading the second argument. \catcode`\\ = 0 \afterassignment\endgroup \expandafter\gdef\csname X#1\endcsname } % Read the last existing aux file, if any. No error if none exists. \def\readauxfile{\begingroup \catcode`\^^@=\other \catcode`\^^A=\other \catcode`\^^B=\other \catcode`\^^C=\other \catcode`\^^D=\other \catcode`\^^E=\other \catcode`\^^F=\other \catcode`\^^G=\other \catcode`\^^H=\other \catcode`\^^K=\other \catcode`\^^L=\other \catcode`\^^N=\other \catcode`\^^P=\other \catcode`\^^Q=\other \catcode`\^^R=\other \catcode`\^^S=\other \catcode`\^^T=\other \catcode`\^^U=\other \catcode`\^^V=\other \catcode`\^^W=\other \catcode`\^^X=\other \catcode`\^^Z=\other \catcode`\^^[=\other \catcode`\^^\=\other \catcode`\^^]=\other \catcode`\^^^=\other \catcode`\^^_=\other \catcode`\@=\other \catcode`\^=\other % It was suggested to define this as 7, which would allow ^^e4 etc. % in xref tags, i.e., node names. But since ^^e4 notation isn't % supported in the main text, it doesn't seem desirable. Furthermore, % that is not enough: for node names that actually contain a ^ % character, we would end up writing a line like this: 'xrdef {'hat % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first % argument, and \hat is not an expandable control sequence. It could % all be worked out, but why? Either we support ^^ or we don't. % % The other change necessary for this was to define \auxhat: % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter % and then to call \auxhat in \setq. % \catcode`\~=\other \catcode`\[=\other \catcode`\]=\other \catcode`\"=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\$=\other \catcode`\#=\other \catcode`\&=\other \catcode`+=\other % avoid \+ for paranoia even though we've turned it off % Make the characters 128-255 be printing characters {% \count 1=128 \def\loop{% \catcode\count 1=\other \advance\count 1 by 1 \ifnum \count 1<256 \loop \fi }% }% % The aux file uses ' as the escape (for now). % Turn off \ as an escape so we do not lose on % entries which were dumped with control sequences in their names. % For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^ % Reference to such entries still does not work the way one would wish, % but at least they do not bomb out when the aux file is read in. \catcode`\{=1 \catcode`\}=2 \catcode`\%=\other \catcode`\'=0 \catcode`\\=\other % \openin 1 \jobname.aux \ifeof 1 \else \closein 1 \input \jobname.aux \global\havexrefstrue \global\warnedobstrue \fi % Open the new aux file. TeX will close it automatically at exit. \openout\auxfile=\jobname.aux \endgroup} % Footnotes. \newcount \footnoteno % The trailing space in the following definition for supereject is % vital for proper filling; pages come out unaligned when you do a % pagealignmacro call if that space before the closing brace is % removed. (Generally, numeric constants should always be followed by a % space to prevent strange expansion errors.) \def\supereject{\par\penalty -20000\footnoteno =0 } % @footnotestyle is meaningful for info output only. \let\footnotestyle=\comment \let\ptexfootnote=\footnote {\catcode `\@=11 % % Auto-number footnotes. Otherwise like plain. \gdef\footnote{% \global\advance\footnoteno by \@ne \edef\thisfootno{$^{\the\footnoteno}$}% % % In case the footnote comes at the end of a sentence, preserve the % extra spacing after we do the footnote number. \let\@sf\empty \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi % % Remove inadvertent blank space before typesetting the footnote number. \unskip \thisfootno\@sf \footnotezzz }% % Don't bother with the trickery in plain.tex to not require the % footnote text as a parameter. Our footnotes don't need to be so general. % % Oh yes, they do; otherwise, @ifset and anything else that uses % \parseargline fail inside footnotes because the tokens are fixed when % the footnote is read. --karl, 16nov96. % \long\gdef\footnotezzz{\insert\footins\bgroup % We want to typeset this text as a normal paragraph, even if the % footnote reference occurs in (for example) a display environment. % So reset some parameters. \interlinepenalty\interfootnotelinepenalty \splittopskip\ht\strutbox % top baseline for broken footnotes \splitmaxdepth\dp\strutbox \floatingpenalty\@MM \leftskip\z@skip \rightskip\z@skip \spaceskip\z@skip \xspaceskip\z@skip \parindent\defaultparindent % % Hang the footnote text off the number. \hang \textindent{\thisfootno}% % % Don't crash into the line above the footnote text. Since this % expands into a box, it must come within the paragraph, lest it % provide a place where TeX can split the footnote. \footstrut \futurelet\next\fo@t } \def\fo@t{\ifcat\bgroup\noexpand\next \let\next\f@@t \else\let\next\f@t\fi \next} \def\f@@t{\bgroup\aftergroup\@foot\let\next} \def\f@t#1{#1\@foot} \def\@foot{\strut\egroup} }%end \catcode `\@=11 % Set the baselineskip to #1, and the lineskip and strut size % correspondingly. There is no deep meaning behind these magic numbers % used as factors; they just match (closely enough) what Knuth defined. % \def\lineskipfactor{.08333} \def\strutheightpercent{.70833} \def\strutdepthpercent {.29167} % \def\setleading#1{% \normalbaselineskip = #1\relax \normallineskip = \lineskipfactor\normalbaselineskip \normalbaselines \setbox\strutbox =\hbox{% \vrule width0pt height\strutheightpercent\baselineskip depth \strutdepthpercent \baselineskip }% } % @| inserts a changebar to the left of the current line. It should % surround any changed text. This approach does *not* work if the % change spans more than two lines of output. To handle that, we would % have adopt a much more difficult approach (putting marks into the main % vertical list for the beginning and end of each change). % \def\|{% % \vadjust can only be used in horizontal mode. \leavevmode % % Append this vertical mode material after the current line in the output. \vadjust{% % We want to insert a rule with the height and depth of the current % leading; that is exactly what \strutbox is supposed to record. \vskip-\baselineskip % % \vadjust-items are inserted at the left edge of the type. So % the \llap here moves out into the left-hand margin. \llap{% % % For a thicker or thinner bar, change the `1pt'. \vrule height\baselineskip width1pt % % This is the space between the bar and the text. \hskip 12pt }% }% } % For a final copy, take out the rectangles % that mark overfull boxes (in case you have decided % that the text looks ok even though it passes the margin). % \def\finalout{\overfullrule=0pt} % @image. We use the macros from epsf.tex to support this. % If epsf.tex is not installed and @image is used, we complain. % % Check for and read epsf.tex up front. If we read it only at @image % time, we might be inside a group, and then its definitions would get % undone and the next image would fail. \openin 1 = epsf.tex \ifeof 1 \else \closein 1 % Do not bother showing banner with post-v2.7 epsf.tex (available in % doc/epsf.tex until it shows up on ctan). \def\epsfannounce{\toks0 = }% \input epsf.tex \fi % \newif\ifwarnednoepsf \newhelp\noepsfhelp{epsf.tex must be installed for images to work. It is also included in the Texinfo distribution, or you can get it from ftp://ftp.tug.org/tex/epsf.tex.} % % Only complain once about lack of epsf.tex. \def\image#1{% \ifx\epsfbox\undefined \ifwarnednoepsf \else \errhelp = \noepsfhelp \errmessage{epsf.tex not found, images will be ignored}% \global\warnednoepsftrue \fi \else \imagexxx #1,,,\finish \fi } % % Arguments to @image: % #1 is (mandatory) image filename; we tack on .eps extension. % #2 is (optional) width, #3 is (optional) height. % #4 is just the usual extra ignored arg for parsing this stuff. \def\imagexxx#1,#2,#3,#4\finish{% % \epsfbox itself resets \epsf?size at each figure. \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi % If the image is by itself, center it. \ifvmode \nobreak\medskip \nobreak \centerline{\epsfbox{#1.eps}}% \bigbreak \else \epsfbox{#1.eps}% \fi } \message{paper sizes,} % And other related parameters. \newdimen\defaultparindent \defaultparindent = 15pt \chapheadingskip = 15pt plus 4pt minus 2pt \secheadingskip = 12pt plus 3pt minus 2pt \subsecheadingskip = 9pt plus 2pt minus 2pt % Prevent underfull vbox error messages. \vbadness = 10000 % Don't be so finicky about underfull hboxes, either. \hbadness = 2000 % Following George Bush, just get rid of widows and orphans. \widowpenalty=10000 \clubpenalty=10000 % Use TeX 3.0's \emergencystretch to help line breaking, but if we're % using an old version of TeX, don't do anything. We want the amount of % stretch added to depend on the line length, hence the dependence on % \hsize. This makes it come to about 9pt for the 8.5x11 format. We % call this whenever the paper size is set. % \def\setemergencystretch{% \ifx\emergencystretch\thisisundefined % Allow us to assign to \emergencystretch anyway. \def\emergencystretch{\dimen0}% \else \emergencystretch = \hsize \divide\emergencystretch by 45 \fi } % Parameters in order: 1) textheight; 2) textwidth; 3) voffset; % 4) hoffset; 5) binding offset; 6) topskip. Then whoever calls us can % set \parskip and call \setleading for \baselineskip. % \def\internalpagesizes#1#2#3#4#5#6{% \voffset = #3\relax \topskip = #6\relax \splittopskip = \topskip % \vsize = #1\relax \advance\vsize by \topskip \outervsize = \vsize \advance\outervsize by 2\topandbottommargin \pageheight = \vsize % \hsize = #2\relax \outerhsize = \hsize \advance\outerhsize by 0.5in \pagewidth = \hsize % \normaloffset = #4\relax \bindingoffset = #5\relax % \parindent = \defaultparindent \setemergencystretch } % @letterpaper (the default). \def\letterpaper{{\globaldefs = 1 \parskip = 3pt plus 2pt minus 1pt \setleading{13.2pt}% % % If page is nothing but text, make it come out even. \internalpagesizes{46\baselineskip}{6in}{\voffset}{.25in}{\bindingoffset}{36pt}% }} % Use @smallbook to reset parameters for 7x9.5 (or so) format. \def\smallbook{{\globaldefs = 1 \parskip = 2pt plus 1pt \setleading{12pt}% % \internalpagesizes{7.5in}{5.in}{\voffset}{.25in}{\bindingoffset}{16pt}% % \lispnarrowing = 0.3in \tolerance = 700 \hfuzz = 1pt \contentsrightmargin = 0pt \deftypemargin = 0pt \defbodyindent = .5cm % \let\smalldisplay = \smalldisplayx \let\smallexample = \smalllispx \let\smallformat = \smallformatx \let\smalllisp = \smalllispx }} % Use @afourpaper to print on European A4 paper. \def\afourpaper{{\globaldefs = 1 \setleading{12pt}% \parskip = 3pt plus 2pt minus 1pt % \internalpagesizes{53\baselineskip}{160mm}{\voffset}{4mm}{\bindingoffset}{44pt}% % \tolerance = 700 \hfuzz = 1pt }} % A specific text layout, 24x15cm overall, intended for A4 paper. Top margin % 29mm, hence bottom margin 28mm, nominal side margin 3cm. \def\afourlatex{{\globaldefs = 1 \setleading{13.6pt}% % \afourpaper \internalpagesizes{237mm}{150mm}{3.6mm}{3.6mm}{3mm}{7mm}% % \globaldefs = 0 }} % Use @afourwide to print on European A4 paper in wide format. \def\afourwide{% \afourpaper \internalpagesizes{9.5in}{6.5in}{\hoffset}{\normaloffset}{\bindingoffset}{7mm}% % \globaldefs = 0 } % @pagesizes TEXTHEIGHT[,TEXTWIDTH] % Perhaps we should allow setting the margins, \topskip, \parskip, % and/or leading, also. Or perhaps we should compute them somehow. % \def\pagesizes{\parsearg\pagesizesxxx} \def\pagesizesxxx#1{\pagesizesyyy #1,,\finish} \def\pagesizesyyy#1,#2,#3\finish{{% \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi \globaldefs = 1 % \parskip = 3pt plus 2pt minus 1pt \setleading{13.2pt}% % \internalpagesizes{#1}{\hsize}{\voffset}{\normaloffset}{\bindingoffset}{44pt}% }} % Set default to letter. % \letterpaper \message{and turning on texinfo input format.} % Define macros to output various characters with catcode for normal text. \catcode`\"=\other \catcode`\~=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\+=\other \def\normaldoublequote{"} \def\normaltilde{~} \def\normalcaret{^} \def\normalunderscore{_} \def\normalverticalbar{|} \def\normalless{<} \def\normalgreater{>} \def\normalplus{+} % This macro is used to make a character print one way in ttfont % where it can probably just be output, and another way in other fonts, % where something hairier probably needs to be done. % % #1 is what to print if we are indeed using \tt; #2 is what to print % otherwise. Since all the Computer Modern typewriter fonts have zero % interword stretch (and shrink), and it is reasonable to expect all % typewriter fonts to have this, we can check that font parameter. % \def\ifusingtt#1#2{\ifdim \fontdimen3\the\font=0pt #1\else #2\fi} % Turn off all special characters except @ % (and those which the user can use as if they were ordinary). % Most of these we simply print from the \tt font, but for some, we can % use math or other variants that look better in normal text. \catcode`\"=\active \def\activedoublequote{{\tt\char34}} \let"=\activedoublequote \catcode`\~=\active \def~{{\tt\char126}} \chardef\hat=`\^ \catcode`\^=\active \def^{{\tt \hat}} \catcode`\_=\active \def_{\ifusingtt\normalunderscore\_} % Subroutine for the previous macro. \def\_{\leavevmode \kern.06em \vbox{\hrule width.3em height.1ex}} \catcode`\|=\active \def|{{\tt\char124}} \chardef \less=`\< \catcode`\<=\active \def<{{\tt \less}} \chardef \gtr=`\> \catcode`\>=\active \def>{{\tt \gtr}} \catcode`\+=\active \def+{{\tt \char 43}} %\catcode 27=\active %\def^^[{$\diamondsuit$} % Set up an active definition for =, but don't enable it most of the time. {\catcode`\==\active \global\def={{\tt \char 61}}} \catcode`+=\active \catcode`\_=\active % If a .fmt file is being used, characters that might appear in a file % name cannot be active until we have parsed the command line. % So turn them off again, and have \everyjob (or @setfilename) turn them on. % \otherifyactive is called near the end of this file. \def\otherifyactive{\catcode`+=\other \catcode`\_=\other} \catcode`\@=0 % \rawbackslashxx output one backslash character in current font \global\chardef\rawbackslashxx=`\\ %{\catcode`\\=\other %@gdef@rawbackslashxx{\}} % \rawbackslash redefines \ as input to do \rawbackslashxx. {\catcode`\\=\active @gdef@rawbackslash{@let\=@rawbackslashxx }} % \normalbackslash outputs one backslash in fixed width font. \def\normalbackslash{{\tt\rawbackslashxx}} % Say @foo, not \foo, in error messages. \escapechar=`\@ % \catcode 17=0 % Define control-q \catcode`\\=\active % Used sometimes to turn off (effectively) the active characters % even after parsing them. @def@turnoffactive{@let"=@normaldoublequote @let\=@realbackslash @let~=@normaltilde @let^=@normalcaret @let_=@normalunderscore @let|=@normalverticalbar @let<=@normalless @let>=@normalgreater @let+=@normalplus} @def@normalturnoffactive{@let"=@normaldoublequote @let\=@normalbackslash @let~=@normaltilde @let^=@normalcaret @let_=@normalunderscore @let|=@normalverticalbar @let<=@normalless @let>=@normalgreater @let+=@normalplus} % Make _ and + \other characters, temporarily. % This is canceled by @fixbackslash. @otherifyactive % If a .fmt file is being used, we don't want the `\input texinfo' to show up. % That is what \eatinput is for; after that, the `\' should revert to printing % a backslash. % @gdef@eatinput input texinfo{@fixbackslash} @global@let\ = @eatinput % On the other hand, perhaps the file did not have a `\input texinfo'. Then % the first `\{ in the file would cause an error. This macro tries to fix % that, assuming it is called before the first `\' could plausibly occur. % Also back turn on active characters that might appear in the input % file name, in case not using a pre-dumped format. % @gdef@fixbackslash{@ifx\@eatinput @let\ = @normalbackslash @fi @catcode`+=@active @catcode`@_=@active} % These look ok in all fonts, so just make them not special. The @rm below % makes sure that the current font starts out as the newly loaded cmr10 @catcode`@$=@other @catcode`@%=@other @catcode`@&=@other @catcode`@#=@other @textfonts @rm @c Local variables: @c eval: (add-hook 'write-file-hooks 'time-stamp) @c page-delimiter: "^\\\\message" @c time-stamp-start: "def\\\\texinfoversion{" @c time-stamp-format: "%:y-%02m-%02d" @c time-stamp-end: "}" @c End: mmm-mode-0.5.1/Makefile.am0000664000175000017500000000113012111514564012177 00000000000000## Process this file with automake to produce Makefile.in ## The MMM Mode distribution is `flat', so we have no SUBDIRS macro. lisp_LISP = mmm-compat.el mmm-vars.el mmm-utils.el mmm-auto.el \ mmm-region.el mmm-class.el mmm-cmds.el mmm-mode.el \ mmm-sample.el mmm-mason.el mmm-univ.el mmm-rpm.el mmm-cweb.el \ mmm-noweb.el mmm-myghty.el mmm-erb.el info_TEXINFOS = mmm.texinfo # This is a hack IMO. Automake should recognize lisp files as # "sources" and include them in the distribution, but it doesn't. EXTRA_DIST = $(lisp_LISP) README.Mason FAQ # See also `elisp-comp' for another hack. mmm-mode-0.5.1/mmm-region.el0000664000175000017500000010220312113442736012542 00000000000000;;; mmm-region.el --- Manipulating and behavior of MMM submode regions ;; Copyright (C) 2000 by Michael Abraham Shulman ;; Copyright (C) 2012, 2013 by Dmitry Gutov ;; Author: Michael Abraham Shulman ;;{{{ GPL ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file provides the functions and variables to create, delete, ;; and inspect submode regions, as well as functions that make them ;; behave like the submode with respect to syntax tables, local maps, ;; font lock, etc. ;; See mmm-class.el for functions which scan the buffer and decide ;; where to create regions. ;;; Code: (require 'cl) (require 'font-lock) (require 'mmm-compat) (require 'mmm-utils) (require 'mmm-auto) (require 'mmm-vars) ;; INSPECTION ;;{{{ Current Overlays ;; Emacs counts an overlay starting at POS as "at" POS, but not an ;; overlay ending at POS. XEmacs is more sensible and uses beg- and ;; end-stickiness to determine whether an endpoint is within an ;; extent. Here we want to act like XEmacs does. (defsubst mmm-overlay-at (&optional pos type) "Return the highest-priority MMM Mode overlay at POS. See `mmm-included-p' for the values of TYPE." (car (mmm-overlays-at pos type))) (defun mmm-overlays-at (&optional pos type) "Return a list of the MMM overlays at POS, in decreasing priority. See `mmm-included-p' for the values of TYPE." (or pos (setq pos (point))) (mmm-sort-overlays (remove-if-not #'(lambda (ovl) (and (overlay-get ovl 'mmm) (mmm-included-p ovl pos type))) ;; XEmacs complains about positions outside the buffer (overlays-in (max (1- pos) (point-min)) (min (1+ pos) (point-max)))))) (defun mmm-included-p (ovl pos &optional type) "Return true if the overlay OVL contains POS. If OVL strictly contains POS, always return true. If OVL starts or ends at POS, return true or false based on the value of TYPE, which should be one of nil, `beg', `end', `none', or `all'. * If TYPE is nil, return true for an overlay starting at POS only if it is beg-sticky, and for one ending at POS only if it is end-sticky. * If TYPE is `beg', return true for any overlay starting at POS but false for any ending at POS. * If TYPE is `end', return true for any overlay ending at POS but false for any starting at POS. * If TYPE is `all', return true for any overlay starting or ending at POS. * If TYPE is `none' \(or any other value), return false for any overlay starting or ending at POS." (let ((beg (overlay-start ovl)) (end (overlay-end ovl))) (cond ((and (= beg pos) (= end pos)) ;; Do the Right Thing for zero-width overlays (case type ((nil) (and (overlay-get ovl 'beg-sticky) (overlay-get ovl 'end-sticky))) ((none) nil) (t t))) ((= beg pos) (case type ((nil) (overlay-get ovl 'beg-sticky)) ((beg all) t) (t nil))) ((= end pos) (case type ((nil) (overlay-get ovl 'end-sticky)) ((end all) t) (t nil))) ((and (> end pos) (< beg pos)) t)))) ;;; `mmm-overlays-in' has been retired as altogether too confusing a ;;; name, when what is really meant is one of the following three: (defun mmm-overlays-containing (start stop) "Return all MMM overlays containing the region START to STOP. The overlays are returned in order of decreasing priority. No attention is paid to stickiness." (mmm-sort-overlays (remove-if-not #'(lambda (ovl) (and (overlay-get ovl 'mmm) (<= (overlay-start ovl) start) (>= (overlay-end ovl) stop))) (overlays-in (max start (point-min)) (min stop (point-max)))))) (defun mmm-overlays-contained-in (start stop) "Return all MMM overlays entirely contained in START to STOP. The overlays are returned in order of decreasing priority. No attention is paid to stickiness." (mmm-sort-overlays (remove-if-not #'(lambda (ovl) (and (overlay-get ovl 'mmm) (>= (overlay-start ovl) start) (<= (overlay-end ovl) stop))) (overlays-in (max start (point-min)) (min stop (point-max)))))) (defun mmm-overlays-overlapping (start stop) "Return all MMM overlays overlapping the region START to STOP. The overlays are returned in order of decreasing priority. No attention is paid to stickiness." (mmm-sort-overlays (remove-if-not #'(lambda (ovl) (overlay-get ovl 'mmm)) (overlays-in (max start (point-min)) (min stop (point-max)))))) (defun mmm-sort-overlays (overlays) "Sort OVERLAYS in order of decreasing priority." (sort (copy-list overlays) #'(lambda (x y) (> (or (overlay-get x 'priority) 0) (or (overlay-get y 'priority) 0))))) ;;}}} ;;{{{ Current Submode (defvar mmm-current-overlay nil "What submode region overlay we think we are currently in. May be out of date; call `mmm-update-current-submode' to correct it.") (make-variable-buffer-local 'mmm-current-overlay) (defvar mmm-previous-overlay nil "What submode region overlay we were in just before this one. Set by `mmm-update-current-submode'.") (make-variable-buffer-local 'mmm-previous-overlay) (defvar mmm-current-submode nil "What submode we think we are currently in. May be out of date; call `mmm-update-current-submode' to correct it.") (make-variable-buffer-local 'mmm-current-submode) (defvar mmm-previous-submode nil "What submode we were in just before this one. Set by `mmm-update-current-submode'.") (make-variable-buffer-local 'mmm-previous-submode) (defun mmm-update-current-submode (&optional pos) "Update current and previous position variables to POS, or point. Return non-nil if the current region changed. Also deletes overlays that ought to evaporate because their delimiters have disappeared." (mapc #'delete-overlay (remove-if #'(lambda (ovl) (or (not (eq (overlay-get ovl 'mmm-evap) 'front)) (overlay-buffer (overlay-get ovl 'front)))) (mmm-overlays-at pos))) (let ((ovl (mmm-overlay-at pos))) (if (eq ovl mmm-current-overlay) nil (mmm-set-current-pair (if ovl (overlay-get ovl 'mmm-mode)) ovl) t))) (defun mmm-set-current-pair (mode ovl) "Set the current submode to MODE, the current overlay to OVL and update the saved previous values." (setq mmm-previous-overlay mmm-current-overlay mmm-previous-submode mmm-current-submode) (setq mmm-current-submode mode mmm-current-overlay ovl)) (defun mmm-submode-at (&optional pos type) "Return the submode at POS \(or point), or NIL if none. See `mmm-included-p' for values of TYPE." (let ((ovl (mmm-overlay-at pos type))) (if ovl (overlay-get ovl 'mmm-mode)))) ;;}}} ;;{{{ Delimiter Matching and Boundaries (defun mmm-match-front (ovl) "Return non-nil if the front delimiter of OVL matches as it should. Sets the match data to the front delimiter, if it is a regexp. Otherwise, calls it as a function with point at the beginning of the front delimiter overlay \(i.e. where the front delimiter ought to start) and one argument being the region overlay. The function should return non-nil if the front delimiter matches correctly, and set the match data appropriately." (let* ((front-ovl (overlay-get ovl 'front)) (front (if front-ovl (overlay-get front-ovl 'match)))) (when front (save-excursion (goto-char (overlay-start front-ovl)) (if (stringp front) ;; It's a regexp (looking-at front) ;; It's a function (funcall front ovl)))))) (defun mmm-match-back (ovl) "Return non-nil if the back delimiter of OVL matches as it should. Sets the match data to the back delimiter, if it is a regexp. Otherwise, calls it as a function with point at the beginning of the back delimiter overlay \(i.e. where the back delimiter ought to start) and one argument being the region overlay. The function should return non-nil if the back delimiter matches correctly, and set the match data appropriately." (let* ((back-ovl (overlay-get ovl 'back)) (back (if back-ovl (overlay-get back-ovl 'match)))) (when back (save-excursion (goto-char (overlay-start back-ovl)) (if (stringp back) ;; It's a regexp (looking-at back) ;; It's a function (funcall back ovl)))))) (defun mmm-front-start (ovl) "Return the position at which the front delimiter of OVL starts." (let ((front (overlay-get ovl 'front))) ;; Overlays which have evaporated become "overlays in no buffer" (if (and front (overlay-buffer front)) (overlay-start front) (overlay-start ovl)))) (defun mmm-back-end (ovl) "Return the position at which the back delimiter of OVL ends." (let ((back (overlay-get ovl 'back))) ;; Overlays which have evaporated become "overlays in no buffer" (if (and back (overlay-buffer back)) (overlay-end back) (overlay-end ovl)))) ;;}}} ;; CREATION & DELETION ;;{{{ Make Submode Regions (defun mmm-valid-submode-region (submode beg end) "Check if the region between BEG and END is valid for SUBMODE. This region must be entirely contained within zero or more existing submode regions, none of which start or end inside it, and it must be a valid child of the highest-priority of those regions, if any. Signals errors, returns `t' if no error." ;; First check if the placement is valid. Every existing region ;; that overlaps this one must contain it in its entirety. (let ((violators (set-difference (mmm-overlays-overlapping beg end) (mmm-overlays-containing beg end)))) (if violators (signal 'mmm-subregion-invalid-placement violators))) ;; Now check if it is inside a valid parent (let ((parent-mode (mmm-submode-at beg 'beg))) (and parent-mode ;; TODO: Actually check parents here. For present purposes, ;; we just make sure we aren't putting a submode inside one ;; of the same type. Actually, what we should really be ;; doing is checking classes/names of regions, not just the ;; submodes. (eq submode parent-mode) (signal 'mmm-subregion-invalid-parent (list parent-mode)))) t) (defun* mmm-make-region (submode beg end &key face front back (evaporation 'front) delimiter-mode front-face back-face display-name (match-front "") (match-back "") (beg-sticky t) (end-sticky t) name creation-hook ) "Make a submode region from BEG to END of SUBMODE. BEG and END are buffer positions or markers with BEG <= END \(although see EVAPORATION below). SUBMODE is a major mode function or a valid argument to `mmm-modename->function'. FACE is a valid display face. FRONT and BACK specify the positions of the front and back delimiters for this region, if any. If FRONT is a buffer position or marker, the front delimiter runs from it to BEG. FRONT can also be a two-element list \(FRONT-BEG FRONT-END) specifying the exact position of the front delimiter. One must have FRONT-BEG < FRONT-END <= BEG. Similarly, BACK may be a buffer position or marker, in which case the back delimiter runs from END to BACK. BACK can also be a two-element list \(BACK-BEG BACK-END) specifying the exact position, in which case we must have END <= BACK-BEG < BACK-END. EVAPORATION specifies under what conditions this submode region should disappear. * If `nil', the region never disappears. This can cause serious problems when using cut-and-paste and is not recommended. * If the value is t, the region disappears whenever it has zero length. This is recommended for manually created regions used for temporary editing convenience. * If the value is `front', the region will disappear whenever the text in its front delimiter disappears, that is, whenever the overlay which marks its front delimiter has zero width. The default value is `front'. However, if the parameter FRONT is nil, then this makes no sense, so the default becomes `t'. Note that if EVAPORATION is `t', then an error is signalled if BEG = END. MATCH-FRONT \(resp. MATCH-BACK) is a regexp or function to match the correct delimiters, see `mmm-match-front' \(resp. `mmm-match-back'). It is ignored if FRONT \(resp. BACK) is nil. At present these are not used much. DELIMITER-MODE specifies the major mode to use for delimiter regions. A `nil' value means they remain in the primary mode. FACE, FRONT-FACE, and BACK-FACE, are faces to use for the region, the front delimiter, and the back delimiter, respectively, under high decoration \(see `mmm-submode-decoration-level'). BEG-STICKY and END-STICKY determine whether the front and back of the region, respectively, are sticky with respect to new insertion. The default is yes. NAME is a string giving the \"name\" of this submode region. Submode regions with the same name are considered part of the same code fragment and formatted accordingly. DISPLAY-NAME is a string to display in the mode line when point is in this submode region. If nil or not given, the name associated with SUBMODE is used. In delimiter regions, \"--\" is shown. CREATION-HOOK should be a function to run after the region is created, with point at the start of the new region." ;; Check placement of region and delimiters (unless (if (eq evaporation t) (< beg end) (<= beg end)) (signal 'mmm-subregion-invalid-placement (list beg end))) (when front (unless (listp front) (setq front (list front beg))) (unless (and (< (car front) (cadr front)) (<= (cadr front) beg)) (signal 'mmm-subregion-invalid-placement front))) (when back (unless (listp back) (setq back (list end back))) (unless (and (< (car back) (cadr back)) (<= end (car back))) (signal 'mmm-subregion-invalid-placement back))) (setq submode (mmm-modename->function submode)) ;; Check embedding in existing regions (mmm-valid-submode-region submode beg end) (mmm-mode-on) (when submode (mmm-update-mode-info submode)) (and (not front) (eq evaporation 'front) (setq evaporation t)) (let ((region-ovl (mmm-make-overlay submode beg end name face beg-sticky end-sticky (or (eq evaporation t) nil) display-name))) ;; Save evaporation type for checking later (overlay-put region-ovl 'mmm-evap evaporation) ;; Calculate priority to supersede anything already there. (overlay-put region-ovl 'priority (length (mmm-overlays-at beg))) ;; Make overlays for the delimiters, with appropriate pointers. (when front (let ((front-ovl (mmm-make-overlay delimiter-mode (car front) (cadr front) nil front-face nil nil t "--" t))) (overlay-put region-ovl 'front front-ovl) (overlay-put front-ovl 'region region-ovl) (overlay-put front-ovl 'match match-front))) (when back (let ((back-ovl (mmm-make-overlay delimiter-mode (car back) (cadr back) nil back-face nil nil t "--" t))) (overlay-put region-ovl 'back back-ovl) (overlay-put back-ovl 'region region-ovl) (overlay-put back-ovl 'match match-back))) ;; Update everything and run all the hooks (mmm-save-all ;; Can be nil when a zero-width region is immediately evaporated (when (overlay-start region-ovl) (goto-char (overlay-start region-ovl))) (mmm-set-current-pair submode region-ovl) (mmm-set-local-variables submode region-ovl) (mmm-run-submode-hook submode) (when creation-hook (funcall creation-hook))) (mmm-update-submode-region) region-ovl)) (defun mmm-make-overlay (submode beg end name face beg-sticky end-sticky evap &optional display-name delim) "Internal function to make submode overlays. Does not handle delimiters. Use `mmm-make-region'." (let ((ovl (make-overlay beg end nil (not beg-sticky) end-sticky))) (mapc #'(lambda (pair) (overlay-put ovl (car pair) (cadr pair))) `((mmm t) ; Mark all submode overlays (mmm-mode ,submode) ,@(if delim '((delim t)) nil) (mmm-local-variables ;; Have to be careful to make new list structure here ,(list* (list 'font-lock-cache-state nil) (list 'font-lock-cache-position (make-marker)) (copy-tree (cdr (assq submode mmm-region-saved-locals-defaults))))) (name ,name) (display-name ,display-name) ;; Need to save these, because there's no way of accessing an ;; overlay's official "front-advance" parameter once it's created. (beg-sticky ,beg-sticky) (end-sticky ,end-sticky) ;; These have special meaning to Emacs (,mmm-evaporate-property ,evap) (face ,(mmm-get-face face submode delim)) )) ovl)) (defun mmm-get-face (face submode &optional delim) (cond ((= mmm-submode-decoration-level 0) nil) ((and (= mmm-submode-decoration-level 2) face) face) (delim 'mmm-delimiter-face) (submode 'mmm-default-submode-face))) ;;}}} ;;{{{ Clear Overlays ;; See also `mmm-clear-current-region'. (defun mmm-clear-overlays (&optional start stop strict) "Clears all MMM overlays overlapping START and STOP. If STRICT, only clear those entirely included in that region." (mapc #'delete-overlay (if strict (mmm-overlays-contained-in (or start (point-min)) (or stop (point-max))) (mmm-overlays-overlapping (or start (point-min)) (or stop (point-max))))) (mmm-update-submode-region)) ;;}}} ;; BASIC UPDATING ;;{{{ Submode Info (defun mmm-update-mode-info (mode &optional force) "Save the global-saved and buffer-saved variables for MODE. Global saving is done on properties of the symbol MODE and buffer saving in `mmm-buffer-saved-locals'. This function must be called for both the dominant mode and all submodes, in each file. Region-saved variables are initialized from `mmm-region-saved-locals-defaults', which is set here as well. See `mmm-save-local-variables'. If FORCE is non-nil, don't quit if the info is already there." (let ((buffer-entry (assq mode mmm-buffer-saved-locals)) (region-entry (assq mode mmm-region-saved-locals-defaults)) global-vars buffer-vars region-vars ;; http://debbugs.gnu.org/13836 buffer-file-truename) (unless (and (not force) (get mode 'mmm-local-variables) buffer-entry region-entry) (let ((temp-buffer (mmm-make-temp-buffer (current-buffer) mmm-temp-buffer-name)) (mmm-in-temp-buffer t)) (unwind-protect (with-current-buffer temp-buffer ;; Handle stupid modes that need the file name set. (when (memq mode mmm-set-file-name-for-modes) (setq buffer-file-name filename)) (funcall mode) (when (featurep 'font-lock) (put mode 'mmm-font-lock-mode font-lock-mode) ;; These can't be in the local variables list, because we ;; replace their actual values, but we want to use their ;; original values elsewhere. (put mode 'mmm-fontify-region-function font-lock-fontify-region-function) (put mode 'mmm-beginning-of-syntax-function (or syntax-begin-function font-lock-beginning-of-syntax-function)) (put mode 'mmm-syntax-propertize-function (and (boundp 'syntax-propertize-function) syntax-propertize-function)) (put mode 'mmm-indent-line-function indent-line-function)) ;; Get variables (setq global-vars (mmm-get-locals 'global) buffer-vars (mmm-get-locals 'buffer) region-vars (mmm-get-locals 'region)) (put mode 'mmm-mode-name mode-name)) (kill-buffer temp-buffer))) (put mode 'mmm-local-variables global-vars) (if buffer-entry (setcdr buffer-entry buffer-vars) (push (cons mode buffer-vars) mmm-buffer-saved-locals)) (if region-entry (setcdr region-entry region-vars) (push (cons mode region-vars) mmm-region-saved-locals-defaults))))) ;;}}} ;;{{{ Updating Hooks (defun mmm-update-submode-region () "Update all MMM properties correctly for the current position. This function and those it calls do the actual work of setting the different keymaps, syntax tables, local variables, etc. for submodes." (when (mmm-update-current-submode) (mmm-save-changed-local-variables mmm-previous-submode mmm-previous-overlay) (let ((mode (or mmm-current-submode mmm-primary-mode))) (mmm-update-mode-info mode) (mmm-set-local-variables mode mmm-current-overlay) (mmm-enable-font-lock mode)) (mmm-set-mode-line) (dolist (func (if mmm-current-overlay (overlay-get mmm-current-overlay 'entry-hook) mmm-primary-mode-entry-hook)) (ignore-errors (funcall func))))) (defun mmm-add-hooks () (if (featurep 'xemacs) (make-local-hook 'post-command-hook)) (add-hook 'post-command-hook 'mmm-update-submode-region nil t) (when mmm-parse-when-idle (add-hook 'pre-command-hook 'mmm-mode-reset-timer nil t) (add-hook 'after-change-functions 'mmm-mode-edit nil t))) (defun mmm-remove-hooks () (remove-hook 'post-command-hook 'mmm-update-submode-region t) (remove-hook 'pre-command-hook 'mmm-mode-reset-timer t) (remove-hook 'after-change-functions 'mmm-mode-edit t)) ;;}}} ;;{{{ Local Variables (defun mmm-get-local-variables-list (type mode) "Filter `mmm-save-local-variables' to match TYPE and MODE. Return a list \(VAR ...). In some cases, VAR will be a cons cell \(GETTER . SETTER) -- see `mmm-save-local-variables'." (mapcan #'(lambda (element) (and (if (and (consp element) (cdr element) (cadr element)) (eq (cadr element) type) (eq type 'global)) (if (and (consp element) (cddr element) (not (eq (caddr element) t))) (if (functionp (caddr element)) (funcall (caddr element)) (member mode (caddr element))) t) (list (if (consp element) (car element) element)))) mmm-save-local-variables)) (defun mmm-get-locals (type) "Get the local variables and values for TYPE from this buffer. Return \((VAR VALUE) ...). In some cases, VAR will be of the form \(GETTER . SETTER) -- see `mmm-save-local-variables'." (mapcan #'(lambda (var) (if (consp var) `((,var ,(funcall (car var)))) (and (boundp var) ;; This seems logical, but screws things up. ;;(local-variable-p var) `((,var ,(symbol-value var)))))) (mmm-get-local-variables-list type major-mode))) ;; FIXME: Has no callers. Used for debugging? (defun mmm-get-saved-local (mode ovl var) "Get the value of the local variable VAR saved for MODE and OVL, if any." (cadr (assq var (mmm-get-saved-local-variables ovl mode)))) ;; FIXME: It's too easy to accidentally pass nil as MODE here. ;; We probably should call this from `mmm-set-current-pair', and not ;; rely on its callers to default to the primary mode when appropriate. ;; Also, incorporate the opmimization from `mmm-fontify-region-list'. (defun mmm-set-local-variables (mode ovl) "Set all the local variables saved for MODE and OVL. Looks up global, buffer and region saves. When MODE is nil, just the region ones." (mapcar #'(lambda (var) ;; (car VAR) may be (GETTER . SETTER) (if (consp (car var)) (funcall (cdar var) (cadr var)) (make-local-variable (car var)) (set (car var) (cadr var)))) (mmm-get-saved-local-variables mode ovl))) (defun mmm-get-saved-local-variables (mode ovl) (append (get mode 'mmm-local-variables) (cdr (assq mode mmm-buffer-saved-locals)) (if ovl (overlay-get ovl 'mmm-local-variables) mmm-region-saved-locals-for-dominant))) (defun mmm-save-changed-local-variables (mode ovl) "Save by-buffer and by-region variables for MODE and OVL. Called when we move to a new submode region, with MODE and OVL the region and mode for the previous position." (let ((buffer-vars (cdr (assq (or mode mmm-primary-mode) mmm-buffer-saved-locals))) (region-vars (if ovl (overlay-get ovl 'mmm-local-variables) mmm-region-saved-locals-for-dominant)) (set-local-value #'(lambda (var) (setcar (cdr var) ;; (car VAR) may be (GETTER . SETTER) (if (consp (car var)) (funcall (caar var)) (symbol-value (car var))))))) (mapc set-local-value buffer-vars) (mapc set-local-value region-vars))) (defun mmm-clear-local-variables () "Clear all buffer- and region-saved variables for current buffer." (setq mmm-buffer-saved-locals () mmm-region-saved-locals-defaults () mmm-region-saved-locals-for-dominant ())) ;;}}} ;; FONT LOCK ;;{{{ Enable Font Lock (defun mmm-enable-font-lock (mode) "Turn on font lock if it is not already on and MODE enables it." (mmm-update-mode-info mode) (and (not font-lock-mode) (get mode 'mmm-font-lock-mode) (font-lock-mode 1))) (defun mmm-update-font-lock-buffer () "Turn on font lock if any mode in the buffer enables it." (if (some #'(lambda (mode) (get mode 'mmm-font-lock-mode)) (cons mmm-primary-mode (mapcar #'(lambda (ovl) (overlay-get ovl 'mmm-mode)) (mmm-overlays-overlapping (point-min) (point-max))))) (font-lock-mode 1) (font-lock-mode 0))) (defun mmm-refontify-maybe (&optional start stop) "Re-fontify from START to STOP, or entire buffer, if enabled." (and font-lock-mode (if (or start stop) (font-lock-fontify-region (or start (point-min)) (or stop (point-max))) (font-lock-fontify-buffer)))) ;;}}} ;;{{{ Get Submode Regions ;;; In theory, these are general functions that have nothing to do ;;; with font-lock, but they aren't used anywhere else, so we might as ;;; well have them close. (defun mmm-submode-changes-in (start stop) "Return a list of all submode-change positions from START to STOP. The list is sorted in order of increasing buffer position." (sort (remove-duplicates (list* start stop (mapcan #'(lambda (ovl) `(,(overlay-start ovl) ,(overlay-end ovl))) (mmm-overlays-overlapping start stop)))) #'<)) (defun mmm-regions-in (start stop) "Return a list of regions of the form (MODE BEG END OVL) whose disjoint union covers the region from START to STOP, including delimiters." (let ((regions (maplist #'(lambda (pos-list) (when (cdr pos-list) (let ((ovl (mmm-overlay-at (car pos-list) 'beg))) (list (if ovl (overlay-get ovl 'mmm-mode) mmm-primary-mode) (car pos-list) (cadr pos-list) ovl)))) (mmm-submode-changes-in start stop)))) (setcdr (last regions 2) nil) regions)) (defun mmm-regions-alist (start stop) "Return a list of lists of the form \(MODE . REGIONS) where REGIONS is a list of elements of the form \(BEG END OVL). The disjoint union all of the REGIONS covers START to STOP." (let ((regions (mmm-regions-in start stop)) alist) (mapc (lambda (region) (let* ((mode (car region)) (elem (cdr region)) (kv (assoc mode alist))) (if kv (push elem (cdr kv)) (push (cons mode (list elem)) alist)))) regions) (mapcar (lambda (kv) (cons (car kv) (nreverse (cdr kv)))) alist))) ;;}}} ;;{{{ Fontify Regions (defun mmm-fontify-region (start stop &optional loudly) "Fontify from START to STOP keeping track of submodes correctly." (let ((saved-mode mmm-current-submode) (saved-ovl mmm-current-overlay)) (unwind-protect (progn (when loudly (message "Fontifying %s with submode regions..." (buffer-name))) ;; Necessary to catch changes in font-lock cache state and position. (mmm-save-changed-local-variables mmm-current-submode mmm-current-overlay) ;; For some reason `font-lock-fontify-block' binds this to nil, thus ;; preventing `mmm-beginning-of-syntax' from doing The Right Thing. ;; I don't know why it does this, but let's undo it here. (let ((font-lock-beginning-of-syntax-function 'mmm-beginning-of-syntax)) (mapc #'(lambda (elt) (when (get (car elt) 'mmm-font-lock-mode) (mmm-fontify-region-list (car elt) (cdr elt)))) (mmm-regions-alist start stop)))) ;; `post-command-hook' contains `mmm-update-submode-region', ;; but jit-lock runs later, so we need to restore local vars now. (mmm-set-current-pair saved-mode saved-ovl) (mmm-set-local-variables (or saved-mode mmm-primary-mode) saved-ovl))) (when loudly (message nil))) (defun mmm-fontify-region-list (mode regions) "Fontify REGIONS, each like \(BEG END), in mode MODE." (save-excursion (let ((func (get mode 'mmm-fontify-region-function)) font-lock-extend-region-functions) (mapc #'(lambda (reg) (goto-char (car reg)) ;; Here we do the same sort of thing that ;; `mmm-update-submode-region' does, but we force it ;; to use a specific mode, and don't save anything, ;; fontify, or change the mode line. (mmm-set-current-pair mode (caddr reg)) (mmm-set-local-variables (unless (eq mmm-previous-submode mode) mode) mmm-current-overlay) (funcall func (car reg) (cadr reg) nil) ;; Catch changes in font-lock cache. (mmm-save-changed-local-variables mmm-current-submode mmm-current-overlay)) regions)))) ;;}}} ;;{{{ Syntax (defun mmm-beginning-of-syntax () (goto-char (let ((ovl (mmm-overlay-at (point))) (func (get (or mmm-current-submode mmm-primary-mode) 'mmm-beginning-of-syntax-function))) (max (if ovl (overlay-start ovl) (point-min)) (if func (progn (funcall func) (point)) (point-min)) (point-min))))) (defun mmm-syntax-propertize-function (start stop) (let ((saved-mode mmm-current-submode) (saved-ovl mmm-current-overlay)) (mmm-save-changed-local-variables mmm-current-submode mmm-current-overlay) (unwind-protect (mapc #'(lambda (elt) (let* ((mode (car elt)) (func (get mode 'mmm-syntax-propertize-function)) (beg (cadr elt)) (end (caddr elt)) (ovl (cadddr elt))) (goto-char beg) (mmm-set-current-pair mode ovl) (mmm-set-local-variables mode mmm-current-overlay) (save-restriction (if mmm-current-overlay (narrow-to-region (overlay-start mmm-current-overlay) (overlay-end mmm-current-overlay)) (narrow-to-region beg end)) (cond (func (funcall func beg end)) (font-lock-syntactic-keywords (let ((syntax-propertize-function nil)) (font-lock-fontify-syntactic-keywords-region beg end))))))) (mmm-regions-in start stop)) (mmm-set-current-pair saved-mode saved-ovl) (mmm-set-local-variables (or saved-mode mmm-primary-mode) saved-ovl)))) ;;}}} ;;{{{ Indentation (defvar mmm-indent-line-function 'mmm-indent-line "The function to call to indent inside a primary mode region. This will be the value of `indent-line-function' for the whole buffer. It's supposed to delegate to the appropriate submode's indentation function. See `mmm-indent-line' as the starting point.") (defun mmm-indent-line () (interactive) (funcall (save-excursion (back-to-indentation) (mmm-update-submode-region) (get (or mmm-current-submode mmm-primary-mode) 'mmm-indent-line-function)))) ;;}}} (provide 'mmm-region) ;;; mmm-region.el ends here mmm-mode-0.5.1/configure.in0000664000175000017500000000161712114106074012462 00000000000000dnl Process this file with autoconf to produce a configure script. AC_INIT() AM_INIT_AUTOMAKE(mmm-mode, 0.5.1) dnl dnl Apparently, if you run a shell window in Emacs, it sets the EMACS dnl environment variable to 't'. Lets undo the damage. dnl if test "${EMACS}" = "t"; then EMACS="" fi AC_ARG_WITH(xemacs, --with-xemacs Use XEmacs to build, [ if test "${withval}" = "yes"; then EMACS=xemacs; else EMACS=${withval}; fi ]) AC_ARG_WITH(emacs, --with-emacs Use Emacs to build, [ if test "${withval}" = "yes"; then EMACS=emacs; else EMACS=${withval}; fi ]) AC_CHECK_PROG(EMACS, xemacs, xemacs, emacs) AM_PATH_LISPDIR AC_EMACS_VERSION dnl Checks for programs. dnl Checks for libraries. dnl Checks for header files. dnl Checks for typedefs, structures, and compiler characteristics. dnl Checks for library functions. AC_SUBST(EMACS) AC_OUTPUT(Makefile) mmm-mode-0.5.1/mmm-noweb.el0000664000175000017500000003260412105042552012371 00000000000000;;; mmm-noweb.el --- MMM submode class for Noweb programs ;; ;; Copyright 2003, 2004 Joe Kelsey ;; ;; The filling, completion and chunk motion commands either taken ;; directly from or inspired by code in: ;; noweb-mode.el - edit noweb files with GNU Emacs ;; Copyright 1995 by Thorsten.Ohl @ Physik.TH-Darmstadt.de ;; with a little help from Norman Ramsey ;; ;;{{{ GPL ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file contains the definition of an MMM Mode submode class for ;; editing Noweb programs. ;; ;; FIXME: The more advanced features don't work: `mmm-name-at' and ;; `mmm-syntax-region' are undefined. Need to dig around in the bug reports ;; and/or discussions, wherever the code using them was submitted. ;;; Code: (require 'cl) (require 'mmm-region) (require 'mmm-vars) (require 'mmm-mode) ;;{{{ Variables (defvar mmm-noweb-code-mode 'fundamental-mode "*Major mode for editing code chunks. This is set to FUNDAMENTAL-MODE by default, but you might want to change this in the Local Variables section of your file to something more appropriate, like C-MODE, FORTRAN-MODE, or even INDENTED-TEXT-MODE.") (defvar mmm-noweb-quote-mode nil "*Major mode for quoted code chunks within documentation chunks. If nil, defaults to `mmm-noweb-code-mode', which see.") (defvar mmm-noweb-quote-string "quote" "*String used to form quoted code submode region names. See `mmm-noweb-quote'.") (defvar mmm-noweb-quote-number 0 "*Starting value appended to `mmm-noweb-quote-string'. See `mmm-noweb-quote'.") (defvar mmm-noweb-narrowing nil "*Narrow the region to the current pair of chunks.") ;;}}} ;;{{{ Support for mmm submode stuff (defun mmm-noweb-chunk (form) "Return the noweb code mode chosen by the user. If the next 100 characters of the buffer contain a string of the form \"-*- MODE -*-\", then return MODE as the chosen mode, otherwise return the value of `mmm-noweb-code-mode'." ;; Look for -*- mode -*- in the first two lines. ;; 120 chars = 40 chars for #! + 80 chars for following line... (if (re-search-forward "-\\*-\\s +\\(\\S-+\\)\\s +-\\*-" (+ (point) 120) t) (let* ((string (match-string-no-properties 1)) (modestr (intern (if (string-match "mode\\'" string) string (concat string "-mode"))))) (or (mmm-ensure-modename modestr) mmm-noweb-code-mode)) mmm-noweb-code-mode)) (defun mmm-noweb-quote (form) "Create a unique name for a quoted code region within a documentation chunk." (or mmm-noweb-quote-mode mmm-noweb-code-mode)) (defun mmm-noweb-quote-name (form) "Create a unique name for a quoted code region within a documentation chunk." (setq mmm-noweb-quote-number (1+ mmm-noweb-quote-number)) (concat mmm-noweb-quote-string "-" (number-to-string mmm-noweb-quote-number))) (defun mmm-noweb-chunk-name (form) "Get the chunk name from FRONT-FORM." (string-match "<<\\(.*\\)>>=" form) (match-string-no-properties 1 form)) ;;}}} ;;{{{ mmm noweb submode group ;; We assume that the global document mode is latex or whatever, the ;; user wants. This class controls the code chunk submodes. We use ;; match-submode to either return the value in mmm-noweb-code-mode or to ;; look at the first line of the chunk for a submode setting. We reset ;; case-fold-search because chunk names are case sensitive. The front ;; string identifies the chunk name between the <<>>. Since this is ;; done, name-match can use the same functions as save-matches for back. ;; Our insert skeleton places a new code chunk and the skel-name lets us ;; optimize the skelton naming to use the inserted string. (mmm-add-group 'noweb '((noweb-chunk :match-submode mmm-noweb-chunk :case-fold-search nil :front "^<<\\(.*\\)>>=" :match-name "~1" :save-name 1 :front-offset (end-of-line 1) :back "^@\\( \\|$\\|\\( %def .*$\\)\\)" :insert ((?c noweb-code "Code Chunk Name: " "\n" @ "<<" str ">>=" @ "\n" _ "\n" @ "@ " @ "\n")) :skel-name t ) (noweb-quote :match-submode mmm-noweb-quote :face mmm-special-submode-face :front "\\[\\[" ; :name-match mmm-noweb-quote-name :back "\\]\\]" :insert ((?q noweb-quote nil @ "[[" @ _ @ "]]" @)) ) )) ;;}}} ;;{{{ Noweb regions (defun mmm-noweb-regions (start stop regexp &optional delim) "Return a liat of regions of the form \(NAME BEG END) that exclude names which match REGEXP." (let* ((remove-next nil) (regions (maplist #'(lambda (pos-list) (if (cdr pos-list) (if remove-next (setq remove-next nil) (let ((name (or (mmm-name-at (car pos-list) 'beg) (symbol-name mmm-primary-mode)))) (if (and regexp (string-match regexp name) ) (progn (setq remove-next t) nil) (list name (car pos-list) (cadr pos-list))))))) (mmm-submode-changes-in start stop t delim)))) ;; The above loop leaves lots of nils in the list... ;; Removing them saves us from having to do the (last x 2) ;; trick that mmm-regions-in does. (setq regions (delq nil regions)))) ;;}}} ;;{{{ Filling, etc (defun mmm-noweb-narrow-to-doc-chunk () "Narrow to the current doc chunk. The current chunk includes all quoted code chunks (i.e., \[\[...\]\]). This function is only valid when called with point in a doc chunk or quoted code chunk." (interactive) (let ((name (mmm-name-at (point)))) (if (or (null name) (string-match "^quote" name)) (let ((prev (cond ((= (point) (point-min)) (point)) (t (cadar (last (mmm-noweb-regions (point-min) (point) "^quote")))))) (next (cond ((= (point) (point-max)) (point)) (t (save-excursion (goto-char (cadr (cadr (mmm-noweb-regions (point) (point-max) "^quote")))) (forward-line -1) (point)))))) (narrow-to-region prev next))))) (defun mmm-noweb-fill-chunk (&optional justify) "Fill the current chunk according to mode. Run `fill-region' on documentation chunks and `indent-region' on code chunks." (interactive "P") (save-restriction (let ((name (mmm-name-at (point)))) (if (and name (not (string-match "^quote" name))) (if (or indent-region-function indent-line-function) (progn (mmm-space-other-regions) (indent-region (overlay-start mmm-current-overlay) (overlay-end mmm-current-overlay) nil)) (error "No indentation functions defined in %s!" major-mode)) (progn (mmm-word-other-regions) (fill-paragraph justify))) (mmm-undo-syntax-other-regions)))) (defun mmm-noweb-fill-paragraph-chunk (&optional justify) "Fill a paragraph in the current chunk." (interactive "P") (save-restriction (let ((name (mmm-name-at (point)))) (if (and name (not (string-match "^quote" name))) (progn (mmm-space-other-regions) (fill-paragraph justify)) (progn (mmm-word-other-regions) (fill-paragraph justify))) (mmm-undo-syntax-other-regions)))) (defun mmm-noweb-fill-named-chunk (&optional justify) "Fill the region containing the named chunk." (interactive "P") (save-restriction (let* ((name (or (mmm-name-at) (symbol-name mmm-primary-mode))) (list (cdr (assoc name (mmm-names-alist (point-min) (point-max)))))) (if (or (string= name (symbol-name mmm-primary-mode)) (string-match "^quote" name)) (progn (mmm-word-other-regions) (do-auto-fill)) (progn (mmm-space-other-regions) (indent-region (caar list) (cadar (last list)) nil))) (mmm-undo-syntax-other-regions)))) (defun mmm-noweb-auto-fill-doc-chunk () "Replacement for `do-auto-fill'." (save-restriction (mmm-noweb-narrow-to-doc-chunk) (mmm-word-other-regions) (do-auto-fill) (mmm-undo-syntax-other-regions))) (defun mmm-noweb-auto-fill-doc-mode () "Install the improved auto fill function, iff necessary." (if auto-fill-function (setq auto-fill-function 'mmm-noweb-auto-fill-doc-chunk))) (defun mmm-noweb-auto-fill-code-mode () "Install the default auto fill function, iff necessary." (if auto-fill-function (setq auto-fill-function 'do-auto-fill))) ;;}}} ;;{{{ Functions on named chunks (defun mmm-noweb-complete-chunk () "Try to complete the chunk name." (interactive) (let ((end (point)) (beg (save-excursion (if (re-search-backward "<<" (save-excursion (beginning-of-line) (point)) t) (match-end 0) nil)))) (if beg (let* ((pattern (buffer-substring beg end)) (alist (mmm-names-alist (point-min) (point-max))) (completion (try-completion pattern alist))) (cond ((eq completion t)) ((null completion) (message "Can't find completion for \"%s\"" pattern) (ding)) ((not (string= pattern completion)) (delete-region beg end) (insert completion) (if (not (looking-at ">>")) (insert ">>"))) (t (message "Making completion list...") (with-output-to-temp-buffer "*Completions*" (display-completion-list (all-completions pattern alist))) (message "Making completion list...%s" "done")))) (message "Not at chunk name...")))) (defvar mmm-noweb-chunk-history nil "History for `mmm-noweb-goto-chunk'.") (defun mmm-noweb-goto-chunk () "Goto the named chunk." (interactive) (widen) (let* ((completion-ignore-case t) (alist (mmm-names-alist (point-min) (point-max))) (chunk (completing-read "Chunk: " alist nil t (mmm-name-at (point)) mmm-noweb-chunk-history))) (goto-char (caadr (assoc chunk alist))))) (defun mmm-noweb-goto-next (&optional cnt) "Goto the continuation of the current chunk." (interactive "p") (widen) (let ((name (mmm-name-at (point)))) (if name (let ((list (cdr (assoc name (mmm-names-alist (overlay-end mmm-current-overlay) (point-max)))))) (if list (goto-char (caar (nthcdr (1- cnt) list)))))))) (defun mmm-noweb-goto-previous (&optional cnt) "Goto the continuation of the current chunk." (interactive "p") (widen) (let ((name (mmm-name-at (point)))) (if name (let ((list (reverse (cdr (assoc name (mmm-names-alist (point-min) (overlay-start mmm-current-overlay))))))) (if list (goto-char (cadar (nthcdr cnt list)))))))) ;;}}} ;;{{{ Key mappings (defvar mmm-noweb-map (make-sparse-keymap)) (defvar mmm-noweb-prefix-map (make-sparse-keymap)) (define-key mmm-noweb-map mmm-mode-prefix-key mmm-noweb-prefix-map) (mmm-define-key ?d 'mmm-noweb-narrow-to-doc-chunk mmm-noweb-prefix-map) (mmm-define-key ?n 'mmm-noweb-goto-next mmm-noweb-prefix-map) (mmm-define-key ?p 'mmm-noweb-goto-previous mmm-noweb-prefix-map) (mmm-define-key ?q 'mmm-noweb-fill-chunk mmm-noweb-prefix-map) ;; Cannot use C-g as goto command, so use C-s. (mmm-define-key ?s 'mmm-noweb-goto-chunk mmm-noweb-prefix-map) (define-key mmm-noweb-prefix-map "\t" 'mmm-noweb-complete-chunk) ;; Don't want to add to either the mmm mode map (used in other mmm ;; buffers) or the local map (used in other major mode buffers), so we ;; make a full-buffer spanning overlay and add the map there. (defun mmm-noweb-bind-keys () (save-restriction (widen) (let ((ovl (make-overlay (point-min) (point-max) nil nil t))) ;; 'keymap', not 'local-map' (overlay-put ovl 'keymap mmm-noweb-map)))) (add-hook 'mmm-noweb-class-hook 'mmm-noweb-bind-keys) ;; TODO: make this overlay go away if mmm is turned off ;;}}} ;; These functions below living here temporarily until a real place is ;; found. (defun mmm-syntax-region-list (syntax regions) "Apply SYNTAX to a list of REGIONS of the form (BEG END). If SYNTAX is not nil, set the syntax-table property of each region. If SYNTAX is nil, remove the region syntax-table property. See `mmm-syntax-region'." (mapcar #'(lambda (reg) (mmm-syntax-region (car reg) (cadr reg) syntax)) regions)) (defun mmm-syntax-other-regions (syntax &optional name) "Apply SYNTAX cell to other regions. Regions are separated by name, using either `mmm-name-at' or the optional NAME to determine the current region name." (if (null name) (setq name (or (mmm-name-at) (symbol-name mmm-primary-mode)))) (mapcar #'(lambda (reg) (if (not (string= (car reg) name)) (mmm-syntax-region-list syntax (cdr reg)))) (mmm-names-alist (point-min) (point-max)))) (defun mmm-word-other-regions () "Give all other regions word syntax." (interactive) (mmm-syntax-other-regions '(2 . 0)) (setq parse-sexp-lookup-properties t)) (defun mmm-space-other-regions () "Give all other regions space syntax." (interactive) (mmm-syntax-other-regions '(0 . 0)) (setq parse-sexp-lookup-properties t)) (defun mmm-undo-syntax-other-regions () "Remove syntax-table property from other regions." (interactive) (mmm-syntax-other-regions nil) (setq parse-sexp-lookup-properties nil)) (provide 'mmm-noweb) ;;; mmm-noweb.el ends here mmm-mode-0.5.1/AUTHORS0000664000175000017500000000073212043063215011216 00000000000000MMM Mode was originally designed and written by Michael Shulman . It was inspired by mmm.el for XEmacs by Gongquan Chen . Recent contributors have included: bishop Joe Kelsey Alan Shutko Michael Alan Dorman Brian P Templeton Yann Dirson Marcus Harnisch and others... mmm-mode-0.5.1/mmm-compat.el0000664000175000017500000001012712106045377012547 00000000000000;;; mmm-compat.el --- MMM Hacks for compatibility with other Emacsen ;; Copyright (C) 2000 by Michael Abraham Shulman ;; Author: Michael Abraham Shulman ;;{{{ GPL ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file provides a number of hacks that are necessary for MMM ;; Mode to function in different Emacsen. MMM Mode is designed for ;; FSF Emacs, but these hacks usually enable it to work ;; almost perfectly in XEmacs 21. ;;; Code: (require 'cl) ;;{{{ Emacsen Detection (defvar mmm-xemacs (featurep 'xemacs) "Whether we are running XEmacs.") ;;}}} ;;{{{ Regexp-Opt (XEmacs) ;; As of XEmacs' xemacs-base package version 1.82, ;; the regexp-opt API is compatible with GNU Emacs. (defalias 'mmm-regexp-opt 'regexp-opt) ;;}}} ;;{{{ Overlays (XEmacs) ;; The main thing we use from FSF Emacs that XEmacs doesn't support ;; are overlays. XEmacs uses extents instead, but comes with a package ;; to emulate overlays. (when mmm-xemacs ;; This does almost everything we need. (require 'overlay)) ;; We also use a couple "special" overlay properties which have ;; different names for XEmacs extents. (defvar mmm-evaporate-property (if (featurep 'xemacs) 'detachable 'evaporate) "The name of the overlay property controlling evaporation.") ;; We don't use this any more, since its behavior is different in FSF ;; and XEmacs: in the one it replaces the buffer's local map, but in ;; the other it gets stacked on top of it. Instead we just set the ;; buffer's local map temporarily. ;;;(defvar mmm-keymap-property ;;; (if (featurep 'xemacs) 'keymap 'local-map) ;;; "The name of the overlay property controlling keymaps.") ;;}}} ;;{{{ Keymaps and Events (XEmacs) ;; In XEmacs, keymaps are a primitive type, while in FSF Emacs, they ;; are a list whose car is the symbol `keymap'. Among other things, ;; this means that they handle default bindings differently. (defmacro mmm-set-keymap-default (keymap binding) (if (featurep 'xemacs) `(set-keymap-default-binding ,keymap ,binding) `(define-key ,keymap [t] ,binding))) ;; In XEmacs, events are a primitive type, while in FSF Emacs, they ;; are represented by characters or vectors. We treat them as vectors. ;; We can use `event-modifiers' in both Emacsen to extract the ;; modifiers, but the function to extract the basic key is different. (defmacro mmm-event-key (event) (if (featurep 'xemacs) `(event-key ,event) `(event-basic-type ,event))) ;;}}} ;;{{{ Skeleton (XEmacs) ;; XEmacs' `skeleton' package doesn't provide `@' to record positions. (defvar skeleton-positions ()) (defun mmm-fixup-skeleton () "Add `@' to `skeleton-further-elements' if XEmacs and not there. This makes `@' in skeletons act approximately like it does in FSF." (and (featurep 'xemacs) (defvar skeleton-further-elements ()) (not (assoc '@ skeleton-further-elements)) (add-to-list 'skeleton-further-elements '(@ ''(push (point) skeleton-positions))))) ;;}}} ;;{{{ Make Temp Buffers (XEmacs) (defmacro mmm-make-temp-buffer (buffer name) "Return a buffer with name based on NAME including the text of BUFFER. This text should not be modified." (if (fboundp 'make-indirect-buffer) `(make-indirect-buffer ,buffer (generate-new-buffer-name ,name)) `(save-excursion (set-buffer (generate-new-buffer ,name)) (insert-buffer ,buffer) (current-buffer)))) (provide 'mmm-compat) ;;; mmm-compat.el ends here mmm-mode-0.5.1/mmm-vars.el0000664000175000017500000012127312114106110012222 00000000000000;;; mmm-vars.el --- Variables for MMM Mode ;; Copyright (C) 2000, 2004 by Michael Abraham Shulman ;; Copyright (C) 2012, 2013 by Dmitry Gutov ;; Author: Michael Abraham Shulman ;;{{{ GPL ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file provides the definitions for the variables used by MMM ;; Mode, as well as several functions to manipulate them. It also ;; defines the errors that MMM Mode can signal. ;;; Code: (require 'mmm-compat) (require 'cl) ;; MISCELLANEOUS ;;{{{ Shut up the Byte Compiler ;; Otherwise it complains about undefined variables. (eval-when-compile (defvar mmm-current-submode) (defvar mmm-save-local-variables) (defvar mmm-mode-string) (defvar mmm-submode-mode-line-format) (defvar mmm-mode-ext-classes-alist) (defvar mmm-mode-prefix-key) (defvar mmm-global-mode) (defvar mmm-primary-mode) (defvar mmm-classes-alist)) ;;}}} ;;{{{ Error Conditions ;; Most of these should be caught internally and never seen by the ;; user, except when the user is creating submode regions manually. ;; Signalled when we try to put a submode region inside one where it ;; isn't meant to go. (put 'mmm-subregion-invalid-parent 'error-conditions '(mmm-subregion-invalid-parent mmm-error error)) (put 'mmm-subregion-invalid-parent 'error-message "Invalid submode region parent") ;; Signalled when we try to put a submode region overlapping others in ;; an invalid way. (put 'mmm-subregion-invalid-placement 'error-conditions '(mmm-subregion-invalid-placement mmm-error error)) (put 'mmm-subregion-invalid-placement 'error-message "Submode region placement invalid") ;; Signalled when we try to apply a submode class that doesn't exist. (put 'mmm-invalid-submode-class 'error-conditions '(mmm-invalid-submode-class mmm-error error)) (put 'mmm-invalid-submode-class 'error-message "Invalid or undefined submode class") ;; Signalled by :match-submode functions when they are unable to ;; resolve a submode. This error should *always* be caught internally ;; and never seen by the user. (put 'mmm-no-matching-submode 'error-conditions '(mmm-no-matching-submode mmm-error error)) (put 'mmm-no-matching-submode 'error-message "Internal error: no matching submode.") ;;}}} ;; USER VARIABLES ;;{{{ Customization Group (defgroup mmm nil "Multiple Major Modes in one buffer." :group 'tools) ;;}}} ;;{{{ Save Local Variables (defvar mmm-c-derived-modes '(c-mode c++-mode objc-mode pike-mode java-mode jde-mode javascript-mode php-mode)) (defvar mmm-save-local-variables `(;; Don't use `function' (#') here!! We're already inside `quote'! major-mode comment-start comment-end (comment-line-start-skip buffer (fortran-mode)) comment-start-skip (comment-column buffer) comment-indent-function comment-line-break-function sentence-end ,@(when mmm-xemacs '(mode-popup-menu (((lambda () current-menubar) . set-buffer-menubar)) )) (font-lock-keywords buffer) font-lock-set-defaults font-lock-major-mode font-lock-keywords-only font-lock-keywords-case-fold-search font-lock-syntax-table font-lock-mark-block-function ; Override this? font-lock-syntactic-keywords parse-sexp-ignore-comments ; Fixes indentation in PHP-mode? ;; Can be different in different buffers (c-basic-offset buffer (c-mode c++-mode objc-mode pike-mode java-mode jde-mode)) ;; These are necessary for C syntax parsing (c-class-key nil ,mmm-c-derived-modes) (c-extra-toplevel-key nil ,mmm-c-derived-modes) (c-inexpr-class-key nil ,mmm-c-derived-modes) (c-conditional-key nil ,mmm-c-derived-modes) semantic-bovinate-toplevel-override semantic-toplevel-bovine-table ;; Indentation style control variables. ;; These have to be localized in Emacs: see `mmm-mode-on'. ,@(mapcar #'(lambda (var) (list var nil mmm-c-derived-modes)) '(c++-template-syntax-table c-<-op-cont-regexp c->-op-cont-regexp c-after-suffixed-type-decl-key c-after-suffixed-type-maybe-decl-key c-any-class-key c-asm-stmt-kwds c-assignment-op-regexp c-backslash-column c-basic-offset c-bitfield-kwds c-block-comment-prefix c-block-decls-with-vars c-block-prefix-charset c-block-stmt-1-key c-block-stmt-1-kwds c-block-stmt-2-key c-block-stmt-2-kwds c-brace-list-key c-cast-parens c-class-key c-class-kwds c-cleanup-list c-colon-type-list-re c-comment-only-line-offset c-comment-prefix-regexp c-comment-start-regexp c-cpp-defined-fns c-current-comment-prefix c-decl-block-key c-decl-hangon-key c-decl-prefix-or-start-re c-decl-prefix-re c-decl-spec-kwds c-decl-start-kwds c-decl-start-re c-doc-comment-start-regexp c-expr-kwds c-file-offsets c-file-style c-hanging-braces-alist c-hanging-colons-alist c-hanging-comment-ender-p c-hanging-comment-starter-p c-hanging-semi\&comma-criteria c-identifier-key c-identifier-last-sym-match c-identifier-start c-identifier-syntax-modifications c-identifier-syntax-table c-in-comment-lc-prefix c-indent-comment-alist c-indent-comments-syntactically-p c-indentation-style c-inexpr-block-kwds c-inexpr-class-kwds c-keywords c-keywords-obarray c-keywords-regexp c-known-type-key c-label-key c-label-kwds c-label-kwds-regexp c-label-minimum-indentation c-lambda-kwds c-literal-start-regexp c-macro-with-semi-re c-nonlabel-token-key c-nonsymbol-chars c-nonsymbol-token-regexp c-not-decl-init-keywords c-offsets-alist c-opt-<>-arglist-start c-opt-<>-arglist-start-in-paren c-opt-<>-sexp-key c-opt-access-key c-opt-asm-stmt-key c-opt-bitfield-key c-opt-block-decls-with-vars-key c-opt-block-stmt-key c-opt-cpp-prefix c-opt-cpp-start c-opt-decl-spec-key c-opt-friend-key c-opt-identifier-concat-key c-opt-inexpr-block-key c-opt-inexpr-brace-list-key c-opt-inexpr-class-key c-opt-lambda-key c-opt-method-key c-opt-postfix-decl-spec-key c-opt-type-component-key c-opt-type-concat-key c-opt-type-modifier-key c-opt-type-suffix-key c-other-decl-block-key c-other-decl-block-kwds c-other-decl-kwds c-overloadable-operators-regexp c-paragraph-separate c-paragraph-start c-paren-stmt-key c-primary-expr-regexp c-primitive-type-key c-primitive-type-kwds c-protection-kwds c-recognize-<>-arglists c-recognize-knr-p c-recognize-paren-inits c-recognize-typeless-decls c-regular-keywords-regexp c-simple-stmt-key c-simple-stmt-kwds c-special-brace-lists c-specifier-key c-specifier-kwds c-stmt-delim-chars c-stmt-delim-chars-with-comma c-symbol-key c-symbol-start c-syntactic-eol c-syntactic-ws-end c-syntactic-ws-start c-type-decl-prefix-key c-type-decl-suffix-key c-type-prefix-key c-prefix-spec-kwds-re c-typedef-key c-typedef-decl-key comment-end comment-start comment-start-skip)) ,@(mapcar (lambda (var) (list var nil '(js-mode))) '(js--quick-match-re js--quick-match-re-func)) ;; Skeleton insertion skeleton-transformation ;; Abbrev mode abbrev-mode local-abbrev-table ;; And finally the syntax table and local map. ((syntax-table . set-syntax-table)) ((current-local-map . use-local-map) buffer) paragraph-separate paragraph-start (whitespace-active-style buffer) (whitespace-display-table buffer) (whitespace-display-table-was-local buffer) (whitespace-font-lock buffer) (whitespace-font-lock-mode buffer) (whitespace-font-lock-keywords buffer) (whitespace-mode buffer) ) "Which local variables to save for major mode regions. Each element has the form \(VARIABLE [TYPE [MODES]]), causing VARIABLE to be saved for all major modes in the list MODES. If MODES is t or absent, the variable is saved for all major modes. MODES can also be a function of no arguments which returns non-nil whenever the variable should be saved. TYPE should be either the symbol `global', meaning to save the variable globally, the symbol `buffer', meaning to save it per buffer, or the symbol `region', meaning to save it for each submode region. If TYPE has any other value, such as nil, or is absent, the variable is saved globally. If all optional parameters are omitted, the element may be simply VARIABLE instead of \(VARIABLE). It is possible for VARIABLE to be not a symbol but a cons cell of the form \(GETTER . SETTER), thus specifying special functions to set and get the value of the \"variable\". This is used for objects like local maps, syntax tables, etc. which need to be installed in a special way. GETTER should be a function of no arguments, and SETTER a function of one. In this case, even if TYPE and MODES are omitted, the list cannot be flattened--it must be \((GETTER . SETTER)). \"Variables\" of this type cannot be seen with `mmm-get-saved-local'. A single variable may appear more than once in this list, with different modes and/or types. If the same mode appears more than once for the same variable with different types, the behavior is undefined. Changing the value of this variable after MMM Mode has been activated in some buffer may produce unpredictable results. Globally saved variables are saved in the mmm-local-variables property of the mode symbol. Buffer saved variables are saved in the alist `mmm-buffer-saved-locals'. Region saved variables are saved in the mmm-local-variables property of the overlay.") (defvar mmm-buffer-saved-locals () "Stores saved local variables for this buffer, by mode. Each element looks like \(MODE \(VAR VALUE) ...).") (make-variable-buffer-local 'mmm-buffer-saved-locals) (defvar mmm-region-saved-locals-defaults () "Stores saved defaults for region-saved locals, by mode. Each element looks like \(MODE \(VAR VALUE) ...). Used to initialize new submode regions.") (make-variable-buffer-local 'mmm-region-saved-locals-defaults) (defvar mmm-region-saved-locals-for-dominant () "Stores saved region locals for the dominant major mode. The dominant major mode is considered to be one region for purposes of saving region variables. Region-saved variables for submode regions are saved as overlay properties.") (make-variable-buffer-local 'mmm-region-saved-locals-for-dominant) ;;}}} ;;{{{ Submode Faces (defgroup mmm-faces nil "Faces and coloring for submode regions. In general, only background colors should be set, to avoid interfering with font-lock." :group 'mmm) (defcustom mmm-submode-decoration-level 1 "*Amount of coloring to use in submode regions. Should be either 0, 1, or 2, representing None, Low, and High amounts of coloring respectively. * None (0) means to use no coloring at all. * Low (1) means to use `mmm-default-submode-face' for all submode regions \(except for \"non-submode\" regions, i.e. those that are of the primary mode) and `mmm-delimiter-face' for region delimiters. * High (2) means to use different faces for different types of submode regions and delimiters, such as initialization code, expressions that are output, declarations, and so on, as specified by the submode class. The default faces are still used for regions that do not specify a face." :group 'mmm-faces :type '(choice (const :tag "None" 0) (const :tag "Low" 1) (const :tag "High" 2))) (defface mmm-init-submode-face '((((background light)) (:background "Pink")) (((background dark)) (:background "MediumOrchid")) (t (:background "Pink"))) "Face used for submodes containing initialization code." :group 'mmm-faces) (defface mmm-cleanup-submode-face '((((background light)) (:background "Wheat")) (((background dark)) (:background "peru")) (t (:background "Wheat"))) "Face used for submodes containing cleanup code." :group 'mmm-faces) (defface mmm-declaration-submode-face '((((background light)) (:background "Aquamarine")) (((background dark)) (:background "DarkTurquoise")) (t (:background "Aquamarine"))) "Face used for submodes containing declarations." :group 'mmm-faces) (defface mmm-comment-submode-face '((((background light)) (:background "SkyBlue")) (((background dark)) (:background "SteelBlue")) (t (:background "SkyBlue"))) "Face used for submodes containing comments and documentation." :group 'mmm-faces) (defface mmm-output-submode-face '((((background light)) (:background "Plum")) (((background dark)) (:background "MediumVioletRed")) (t (:background "Plum"))) "Face used for submodes containing expression that are output." :group 'mmm-faces) (defface mmm-special-submode-face '((((background light)) (:background "MediumSpringGreen")) (((background dark)) (:background "ForestGreen")) (t (:background "MediumSpringGreen"))) "Face used for special submodes not fitting any other category." :group 'mmm-faces) (defface mmm-code-submode-face '((((background light)) (:background "LightGray")) (((background dark)) (:background "DimGray")) (t (:background "LightGray"))) "Face used for submodes containing ordinary code." :group 'mmm-faces) (defface mmm-default-submode-face '((((background light)) (:background "gray85")) (((background dark)) (:background "gray20")) (t (:background "gray85"))) "Face used for all submodes at decoration level 1. Also used at decoration level 2 for submodes not specifying a type." :group 'mmm-faces) (defface mmm-delimiter-face nil "Face used to mark submode delimiters." :group 'mmm-faces) ;;}}} ;;{{{ Mode Line Format (defcustom mmm-mode-string " MMM" "*String to display in mode line as MMM minor mode indicator." :group 'mmm :type 'string) (defcustom mmm-submode-mode-line-format "~M[~m]" "*Format of the mode-line display when point is in a submode region. ~M is replaced by the name of the primary major mode \(which may be replaced by a combined-mode function, see the info documentation). ~m is replaced by the submode region overlay's `display-name' property, if it has one. Otherwise it is replaced by the mode name of the submode region. If `mmm-primary-mode-display-name' is non-nil, then this variable is used even when point is not in a submode region \(i.e. it is in a primary mode region), with ~m being replaced by the value of that variable." :group 'mmm :type 'string) (defvar mmm-primary-mode-display-name nil "If non-nil, displayed as the primary mode name in the mode line. See also `mmm-buffer-mode-display-name'.") (make-variable-buffer-local 'mmm-primary-mode-display-name) (defvar mmm-buffer-mode-display-name nil "If non-nil, displayed in the mode line instead of the primary mode name, which is then shown next to it as if it were a submode when in a primary mode region, i.e. outside all submode regions.") (make-variable-buffer-local 'mmm-buffer-mode-display-name) (defun mmm-set-mode-line () "Set the mode line display correctly for the current submode, according to `mmm-submode-mode-line-format'." (let ((primary (or mmm-primary-mode-display-name (get mmm-primary-mode 'mmm-mode-name))) (submode (and mmm-current-overlay (or (overlay-get mmm-current-overlay 'display-name) (get mmm-current-submode 'mmm-mode-name))))) (if mmm-buffer-mode-display-name (setq mode-name (mmm-format-string mmm-submode-mode-line-format `(("~M" . ,mmm-buffer-mode-display-name) ("~m" . ,(or submode primary))))) (if submode (setq mode-name (mmm-format-string mmm-submode-mode-line-format `(("~M" . ,primary) ("~m" . ,submode)))) (setq mode-name primary)))) (force-mode-line-update)) ;;}}} ;;{{{ Submode Classes (defvar mmm-classes nil "*List of submode classes that apply to a buffer. Generally set in a file local variables list. Can either be one symbol, or a list of symbols. Automatically buffer-local.") (make-variable-buffer-local 'mmm-classes) (defvar mmm-global-classes '(universal) "*List of submode classes that apply to all buffers. Can be overridden in a file local variables list.") ;;}}} ;;{{{ Modes and Extensions (defcustom mmm-mode-ext-classes-alist nil "Alist of submode classes for major modes and/or file extensions. This variable can now be directly modified. Elements look like \(MODE EXT CLASS), where MODE is a major mode, EXT is a regexp to match a filename such as in `auto-mode-alist', and CLASS is a submode class. CLASS is activated in all buffers in mode MODE \(if non-nil) and whose filenames match EXT \(if non-nil). If both MODE and EXT are nil, CLASS is activated in all buffers. If CLASS is the symbol t, MMM Mode is turned on in all buffers matching MODE and EXT, but no classes are activated. See `mmm-global-mode'." :group 'mmm :type '(repeat (list (symbol :tag "Major Mode") (string :tag "Filename Regexp") (symbol :tag "Class"))) :require 'mmm-mode) (defun mmm-add-mode-ext-class (mode ext class) "Add an element to `mmm-mode-ext-classes-alist', which see. That variable can now be directly modified, so this function is unnecessary. It probably won't go away, though." (add-to-list 'mmm-mode-ext-classes-alist (list mode ext class))) ;;}}} ;;{{{ Preferred Major Modes (defcustom mmm-major-mode-preferences '((perl cperl-mode perl-mode) (python python-mode python-mode) (javascript javascript-mode c++-mode) (java jde-mode java-mode c++-mode) (css css-mode c++-mode)) "User preferences about what major modes to use. Each element has the form \(LANGUAGE . MODES) where LANGUAGE is the name of a programming language such as `perl' as a symbol, and MODES is a list of possible major modes to use, such as `cperl-mode' or `perl-mode'. The first element of MODES which is `fboundp' is used for submodes of LANGUAGE. The last element of MODES should be a mode which will always be available." :group 'mmm :type '(repeat (cons symbol (repeat (restricted-sexp :match-alternatives (fboundp)))))) (defun mmm-add-to-major-mode-preferences (language mode &optional default) "Add major mode MODE as acceptable for LANGUAGE. This sets the value of `mmm-major-mode-preferences'. If DEFAULT is non-nil, MODE is added at the front of the list of modes for LANGUAGE. Otherwise, it is added at the end. This may be used by packages to ensure that some mode is present, but not override any user-specified mode." (let ((pair (assq language mmm-major-mode-preferences))) (if pair ;; Existing mode preferences (if default (setcdr pair (cons mode (cdr pair))) (setcdr pair (append (cdr pair) (list mode)))) ;; No existing mode preference (add-to-list 'mmm-major-mode-preferences (list language mode))))) (defun mmm-ensure-modename (symbol) "Return SYMBOL if it is a valid submode name, else nil. Valid submode names are either `fboundp' or present as the `car' of an element in `mmm-major-mode-preferences'." (if (or (fboundp symbol) (assq symbol mmm-major-mode-preferences)) symbol nil)) (defun mmm-modename->function (mode) "Convert MODE to a mode function, nil if impossible. Valid submode names are either `fboundp' or present as the `car' of an element in `mmm-major-mode-preferences'. In the latter case, the first `fboundp' element of the `cdr' is returned, or nil if none." (if (fboundp mode) mode (car (remove-if-not #'fboundp (cdr (assq mode mmm-major-mode-preferences)))))) ;;}}} ;;{{{ Delimiter Regions (defcustom mmm-delimiter-mode 'fundamental-mode "Major mode used by default for delimiter regions. Classes are encouraged to override this by providing a delimiter-mode parameter-- see `mmm-classes-alist'." :group 'mmm :type 'function) ;;}}} ;;{{{ Key Bindings (defcustom mmm-mode-prefix-key [(control ?c) ?%] "Prefix key for the MMM Minor Mode Keymap." :group 'mmm :type 'vector) (defcustom mmm-command-modifiers '(control) "List of key modifiers for MMM command keys. The MMM commands in the MMM Mode map, after `mmm-mode-prefix-key', are bound to default keys with these modifiers added. This variable must be set before MMM Mode is loaded to have an effect. It is suggested that the value of this variable be either nil or \(control), as the default keys are either plain keys or have only a meta modifier. The shift modifier is not particularly portable between Emacsen. The values of this variable and `mmm-insert-modifiers' should be disjoint." :group 'mmm :type '(repeat (symbol :tag "Modifier"))) (defcustom mmm-insert-modifiers '() "List of key modifiers for MMM submode insertion keys. When a key pressed after `mmm-mode-prefix-key' has no MMM Mode command binding, and its modifiers include these, then its basic type, plus any modifiers in addition to these, is looked up in classes' :insert specifications. It is suggested that the value of this variable be either nil or \(control), allowing submode classes to specify the presence or absence of the meta modifier. The shift modifier is not particularly portable between Emacsen. The values of `mmm-command-modifiers' and this variable should be disjoint." :group 'mmm :type '(repeat (symbol :tag "Modifier"))) (defcustom mmm-use-old-command-keys nil "Non-nil means to Use the old command keys for MMM Mode. MMM Mode commands then have no modifier while insertion commands have a control modifier, i.e. `mmm-command-modifiers' is set to nil and `mmm-insert-modifiers' is set to \(control). If nil, the values of these variables are as the default, or whatever the user has set them to. This variable must be set before MMM Mode is loaded." :group 'mmm :type 'boolean) (defun mmm-use-old-command-keys () "Use the old command keys \(no control modifer) in MMM Mode." (setq mmm-command-modifiers '() mmm-insert-modifiers '(control))) ;;}}} ;;{{{ MMM Hooks (defcustom mmm-mode-hook () "Hook run when MMM Mode is enabled in a buffer. A hook named mmm--hook is also run, if it exists. For example, `mmm-html-mode-hook' is run whenever MMM Mode is entered with HTML mode the dominant mode. A hook named mmm--submode-hook is run when a submode region of a given mode is created. For example, `mmm-cperl-mode-submode-hook' is run whenever a CPerl mode submode region is created, in any buffer. When this hooks are run, point is guaranteed to be at the start of the newly created submode region. Finally, a hook named mmm--class-hook is run whenever a buffer is first mmm-ified with a given submode class. For example, `mmm-mason-class-hook' is run whenever the `mason' class is first applied in a buffer." :group 'mmm :type 'hook) (defun mmm-run-constructed-hook (body &optional suffix) "Run the hook named `mmm---hook', if it exists. If SUFFIX is nil or unsupplied, run `mmm--hook' instead." (let ((hook (intern-soft (if suffix (format "mmm-%s-%s-hook" body suffix) (format "mmm-%s-hook" body))))) (if hook (run-hooks hook)))) (defun mmm-run-major-hook () (mmm-run-constructed-hook mmm-primary-mode)) (defun mmm-run-submode-hook (submode) (mmm-run-constructed-hook submode "submode")) (defvar mmm-class-hooks-run () "List of submode classes for which hooks have already been run in the current buffer.") (make-variable-buffer-local 'mmm-class-hooks-run) (defun mmm-run-class-hook (class) (unless (member class mmm-class-hooks-run) (mmm-run-constructed-hook class "class") (add-to-list 'mmm-class-hooks-run class))) (defvar mmm-primary-mode-entry-hook nil "Hook run when point moves into a region of the primary mode. Each submode region can have an `entry-hook' property which is run when they are entered, but since primary mode regions have no overlay to store properties, this is a buffer-local variable. N.B. This variable is not a standard Emacs hook. Unlike Emacs' \"local hooks\" it has *no* global value, only a local one. Its value should always be a list of functions \(possibly empty) and never a single function. It may be used with `add-hook', however.") (make-variable-buffer-local 'mmm-primary-mode-entry-hook) ;;}}} ;;{{{ Major Mode Hook (defcustom mmm-major-mode-hook () "Hook run whenever a new major mode is finished starting up. MMM Mode implements this with a hack \(see comments in the source) so that `mmm-global-mode' will function correctly, but makes this hook available so that others can take advantage of the hack as well. Note that file local variables have *not* been processed by the time this hook is run. If a function needs to inspect them, it should also be added to `find-file-hooks'. However, `find-file-hooks' is not run when creating a non-file-based buffer, or when changing major modes in an existing buffer." :group 'mmm :type 'hook) (defun mmm-run-major-mode-hook () (dolist (func mmm-major-mode-hook) (ignore-errors (funcall func)))) ;;}}} ;;{{{ MMM Global Mode ;;; There's a point to be made that this variable should default to ;;; `maybe' (i.e. not nil and not t), because that's what practically ;;; everyone wants. I subscribe, however, to the view that simply ;;; *loading* a lisp extension should not change the (user-visible) ;;; behavior of Emacs, until it is configured or turned on in some ;;; way, which dictates that the default for this must be nil. (defcustom mmm-global-mode nil "*Specify in which buffers to turn on MMM Mode automatically. - If nil, MMM Mode is never enabled automatically. - If t, MMM Mode is enabled automatically in all buffers. - If any other symbol, MMM mode is enabled only in those buffers that have submode classes associated with them. See `mmm-classes' and `mmm-mode-ext-classes-alist' for more information." :group 'mmm :type '(choice (const :tag "Always" t) (const :tag "Never" nil) (other :tag "Maybe" maybe)) :require 'mmm-mode) ;; These are not traditional editing modes, so mmm makes no sense, and ;; can mess things up seriously if it doesn't know not to try. (defcustom mmm-never-modes '( help-mode Info-mode dired-mode comint-mode telnet-mode shell-mode eshell-mode forms-mode ) "List of modes in which MMM Mode is never activated." :group 'mmm :type '(repeat (symbol :tag "Mode"))) ;;}}} ;;{{{ Buffer File Name (defvar mmm-set-file-name-for-modes '(mew-draft-mode) "List of modes for which the temporary buffers MMM creates have a file name. In these modes, this file name is the same as that of the parent buffer. In general, this has been found to cause more problems than it solves, but some modes require it.") ;;}}} ;;{{{ Idle Parsing (defcustom mmm-parse-when-idle nil "Non-nil to automatically reparse the buffer when it has some modifications and Emacs has been idle for `mmm-idle-timer-delay'." :type 'boolean :group 'mmm) (defcustom mmm-idle-timer-delay 0.2 "Delay in secs before re-parsing after user makes changes." :type 'number :group 'mmm) (make-variable-buffer-local 'mmm-idle-timer-delay) (defvar mmm-mode-parse-timer nil "Private variable.") (make-variable-buffer-local 'mmm-mode-parse-timer) (defvar mmm-mode-buffer-dirty nil "Private variable.") (make-variable-buffer-local 'mmm-mode-buffer-dirty) (defun mmm-mode-edit (beg end len) (setq mmm-mode-buffer-dirty t) (mmm-mode-reset-timer)) (defun mmm-mode-reset-timer () (when mmm-mode-parse-timer (cancel-timer mmm-mode-parse-timer)) (setq mmm-mode-parse-timer (run-with-idle-timer mmm-idle-timer-delay nil #'mmm-mode-idle-reparse (current-buffer)))) (defun mmm-mode-idle-reparse (buffer) (when (buffer-live-p buffer) (with-current-buffer buffer (when mmm-mode-buffer-dirty (mmm-apply-all) (setq mmm-mode-buffer-dirty nil) (setq mmm-mode-parse-timer nil))))) ;;}}} ;; NON-USER VARIABLES ;;{{{ Mode Variable (defvar mmm-mode nil "Non-nil means MMM Mode is turned on in this buffer. Do not set this variable directly; use the function `mmm-mode'.") (make-variable-buffer-local 'mmm-mode) ;;}}} ;;{{{ Primary Mode (defvar mmm-primary-mode nil "The primary major mode in the current buffer.") (make-variable-buffer-local 'mmm-primary-mode) ;;}}} ;;{{{ Classes Alist ;; Notes: ;; 1. :parent could be an all-class argument. Same with :keymap. ;; 2. :match-submode really does have to be distinct from :submode, ;; because 'functionp' isn't enough to distinguish which is meant. (defvar mmm-classes-alist nil "Alist containing all defined mmm submode classes. A submode class is a named recipe for parsing a document into submode regions, and sometimes for inserting new ones while editing. Each element of this alist looks like \(CLASS . ARGS) where CLASS is a symbol naming the submode class and ARGS is a list of keyword arguments, called a \"class specifier\". There are a large number of accepted keyword arguments in the class specifier. The argument CLASSES, if supplied, must be a list of other submode class names, or class specifiers, representing other classes to call recursively. The FACE arguments of these classes are overridden by the FACE argument of this class. If the argument CLASSES is supplied, all other arguments to this class are ignored. That is, \"grouping\" classes can do nothing but group other classes. The argument HANDLER, if supplied, also overrides any other processing. It must be a function, and all the arguments are passed to it as keywords, and it must do everything. See `mmm-ify' for what sorts of things it must do. This back-door interface should be cleaned up. The optional argument FACE gives the display face of the submode regions under high decoration (see `mmm-submode-decoration-level'). It must be a valid face. The standard faces used for submode regions are `mmm-*-submode-face' where * is one of `init', `cleanup', `declaration', `comment', `output', `special', or `code'. A more flexible alternative is the argument MATCH-FACE. MATCH-FACE can be a function, which is called with one argument, the form of the front delimiter \(found from FRONT-FORM, below), and should return the face to use. It can also be an alist, with each element of the form \(DELIM . FACE). If neither CLASSES nor HANDLER are supplied, either SUBMODE or MATCH-SUBMODE must be. SUBMODE specifies the submode to use for the submode regions, a symbol such as `cperl-mode' or `emacs-lisp-mode', while MATCH-SUBMODE must be a function to be called immediately after a match is found for FRONT, which is passed one argument, the form of the front delimiter \(found from FRONT-FORM, below), and return a symbol such as SUBMODE would be set to. If MATCH-SUBMODE detects an invalid match--for example a specified mode which is not `fboundp'--it should \(signal 'mmm-no-matching-submode nil). FRONT and BACK are the means to find the submode regions, and can be either buffer positions \(number-or-markers), regular expressions, or functions. If they are absolute buffer positions, only one submode region is created, from FRONT to BACK. This is generally not used in named classes. \(Unnamed classes are created by interactive commands in `mmm-interactive-history'). If FRONT is a regexp, then that regexp is searched for, and the end of its FRONT-MATCH'th match \(or the beginning thereof, if INCLUDE-FRONT is non-nil), plus FRONT-OFFSET, becomes the beginning of the submode region. If FRONT is a function, that function is called instead, and must act somewhat like a search, in that it should start at point, take one argument as a search bound, and set the match data. A similar pattern is followed for BACK \(the search starts at the beginning of the submode region), save that the beginning of its BACK-MATCH'th match \(or the end, if INCLUDE-BACK is non-nil) becomes the end of the submode region, plus BACK-OFFSET. If SAVE-MATCHES is non-nil, then BACK, if it is a regexp, is formatted by replacing strings of the form \"~N\" by the corresponding value of \(match-string n) after matching FRONT. FRONT-MATCH and BACK-MATCH default to zero. They specify which sub-match of the FRONT and BACK regexps to treat as the delimiter. This number will be passed to any calls to `match-beginning' and company. FRONT- and BACK-OFFSET default to 0. In addition to numbers, they can also be functions to call which should move point to the correct position for the beginning or end of the submode region. Common choices include `beginning-of-line' and `end-of-line', and new functions can of course be written. They can also be lists which will be applied in sequence, such as \(end-of-line 1) meaning move to end of line and then forward one character. FRONT-VERIFY and BACK-VERIFY, if supplied, must be functions that inspect the match data to see if a match found by FRONT or BACK respectively is valid. FRONT-DELIM \(resp. BACK-DELIM), if supplied, can take values like those of FRONT-OFFSET \(resp. BACK-OFFSET), specifying the offset from the start \(resp. end) of the match for FRONT \(resp. BACK) to use as the starting \(resp. ending) point for the front \(resp. back) delimiter. If nil, it means not to make a region for the respective delimiter at all. DELIMITER-MODE, if supplied, specifies what submode to use for the delimiter regions, if any. If `nil', the primary mode is used. If not supplied, `mmm-delimiter-mode' is used. FRONT-FACE and BACK-FACE specify faces to use for displaying the delimiter regions, under high decoration. FRONT-FORM and BACK-FORM, if given, must supply a regexp used to match the *actual* delimiter. If they are strings, they are used as-is. If they are functions, they are called and must inspect the match data. If they are lists, their `car' is taken as the delimiter. The default for both is \(regexp-quote \(match-string 0)). The last case--them being a list--is usually used to set the delimiter to a function. Such a function must take 1-2 arguments, the first being the overlay in question, and the second meaning to insert the delimiter and adjust the overlay rather than just matching the delimiter. See `mmm-match-front', `mmm-match-back', and `mmm-end-current-region'. CASE-FOLD-SEARCH, if specified, controls whether the search is case-insensitive. See `case-fold-search'. It defaults to `t'. CREATION-HOOK, if specified, should be a function which is run whenever a submode region is created, with point at the beginning of the new region. One use for it is to set region-saved local variables \(see `mmm-save-local-variables'). INSERT specifies the keypress insertion spec for such submode regions. INSERT's value should be list of elements of the form \(KEY NAME . SPEC). Each KEY should be either a character, a function key symbol, or a dotted list \(MOD . KEY) where MOD is a symbol for a modifier key. The use of any other modifier than meta is discouraged, as `mmm-insert-modifiers' is sometimes set to \(control), and other modifiers are not very portable. Each NAME should be a symbol representing the insertion for that key. Each SPEC can be either a skeleton, suitable for passing to `skeleton-insert' to create a submode region, or a dotted pair \(OTHER-KEY . ARG) meaning to use the skeleton defined for OTHER-KEY but pass it the argument ARG as the `str' variable, possible replacing a prompt string. Skeletons for insertion should have the symbol `_' where point \(or wrapped text) should go, and the symbol `@' in four different places: at the beginning of the front delimiter, the beginning of the submode region, the end of the submode region, and the end of the back delimiter. If END-NOT-BEGIN is non-nil, it specifies that a BACK delimiter cannot begin a new submode region. MATCH-NAME, if supplied, specifies how to determine the \"name\" for each submode region. It must be a string or a function. If it is a function, it is passed the value of FRONT-FORM and must return the name to use. If it is a string, it is used as-is unless SAVE-NAME has a non-nil value, in which case, the string is interpreted the same as BACK when SAVE-MATCHES is non-nil. If MATCH-NAME is not specified, the regions are unnamed. Regions with the same name are considered part of the same chunk of code, and formatted as such, while unnamed regions are not grouped with any others. As a special optimization for insertion, if SKEL-NAME is non-nil, the insertion code will use the user-prompted string value as the region name, instead of going through the normal matching procedure. PRIVATE, if supplied and non-nil, means that this class is a private or internal class, usually one invoked by another class via :classes, and is not for the user to see.") (defun mmm-add-classes (classes) "Add the submode classes CLASSES to `mmm-classes-alist'." (dolist (class classes) (add-to-list 'mmm-classes-alist class))) (defun mmm-add-group (group classes) "Add CLASSES and a \"grouping class\" named GROUP which calls them all. The CLASSES are all made private, i.e. non-user-visible." (mmm-add-classes (mapcar #'(lambda (class) (append class '(:private t))) classes)) (add-to-list 'mmm-classes-alist (list group :classes (mapcar #'first classes)))) (defun mmm-add-to-group (group classes) "Add CLASSES to the \"grouping class\" named GROUP. The CLASSES are all made private, i.e. non-user-visible." (mmm-add-classes (mapcar #'(lambda (class) (append class '(:private t))) classes)) (mmm-set-class-parameter group :classes (append (mmm-get-class-parameter group :classes) (mapcar #'first classes)))) ;;}}} ;;{{{ Version Number (defconst mmm-version "0.5.1" "Current version of MMM Mode.") (defun mmm-version () (interactive) (message "MMM Mode version %s by Michael Abraham Shulman" mmm-version)) ;;}}} ;;{{{ Temp Buffer Name (defvar mmm-temp-buffer-name "mmm-temp-buffer" "Name for temporary buffers created by MMM Mode. Using non-special name, so that font-lock-mode will be enabled automatically when appropriate, and will set all related vars.") (defvar mmm-in-temp-buffer nil "Bound to t when working in the temp buffer.") ;;}}} ;;{{{ Interactive History (defvar mmm-interactive-history nil "History of interactive mmm-ification in the current buffer. Elements are either submode class symbols or class specifications. See `mmm-classes-alist' for more information.") (make-variable-buffer-local 'mmm-interactive-history) (defun mmm-add-to-history (class) (add-to-list 'mmm-interactive-history class)) (defun mmm-clear-history () "Clears history of interactive mmm-ification in current buffer." (interactive) (setq mmm-interactive-history nil)) ;;}}} ;;{{{ Mode/Ext Manipulation (defvar mmm-mode-ext-classes () "List of classes associated with current buffer by mode and filename. Set automatically from `mmm-mode-ext-classes-alist'.") (make-variable-buffer-local 'mmm-mode-ext-classes) (defun mmm-get-mode-ext-classes () "Return classes for current buffer from major mode and filename. Uses `mmm-mode-ext-classes-alist' to find submode classes." (or mmm-mode-ext-classes (setq mmm-mode-ext-classes (mapcar #'third (remove-if-not #'mmm-mode-ext-applies mmm-mode-ext-classes-alist))))) (defun mmm-clear-mode-ext-classes () "Clear classes added by major mode and filename." (setq mmm-mode-ext-classes nil)) (defun mmm-mode-ext-applies (element) (destructuring-bind (mode ext class) element (and (if mode (eq mode ;; If MMM is on in this buffer, use the primary mode, ;; otherwise use the normal indicator. (or mmm-primary-mode major-mode)) t) (if ext (and (buffer-file-name) (save-match-data (string-match ext (buffer-file-name)))) t)))) (defun mmm-get-all-classes (global) "Return a list of all classes applicable to the current buffer. These come from mode/ext associations, `mmm-classes', and interactive history, as well as `mmm-global-classes' if GLOBAL is non-nil." (append mmm-interactive-history (if (listp mmm-classes) mmm-classes (list mmm-classes)) (if global mmm-global-classes ()) (mmm-get-mode-ext-classes))) ;;}}} (provide 'mmm-vars) ;;; mmm-vars.el ends here mmm-mode-0.5.1/mdate-sh0000775000175000017500000000516712043063215011605 00000000000000#!/bin/sh # Get modification time of a file or directory and pretty-print it. # Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. # written by Ulrich Drepper , June 1995 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Prevent date giving response in another language. LANG=C export LANG LC_ALL=C export LC_ALL LC_TIME=C export LC_TIME # Get the extended ls output of the file or directory. # On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below. if ls -L /dev/null 1>/dev/null 2>&1; then set - x`ls -L -l -d $1` else set - x`ls -l -d $1` fi # The month is at least the fourth argument # (3 shifts here, the next inside the loop). shift shift shift # Find the month. Next argument is day, followed by the year or time. month= until test $month do shift case $1 in Jan) month=January; nummonth=1;; Feb) month=February; nummonth=2;; Mar) month=March; nummonth=3;; Apr) month=April; nummonth=4;; May) month=May; nummonth=5;; Jun) month=June; nummonth=6;; Jul) month=July; nummonth=7;; Aug) month=August; nummonth=8;; Sep) month=September; nummonth=9;; Oct) month=October; nummonth=10;; Nov) month=November; nummonth=11;; Dec) month=December; nummonth=12;; esac done day=$2 # Here we have to deal with the problem that the ls output gives either # the time of day or the year. case $3 in *:*) set `date`; eval year=\$$# case $2 in Jan) nummonthtod=1;; Feb) nummonthtod=2;; Mar) nummonthtod=3;; Apr) nummonthtod=4;; May) nummonthtod=5;; Jun) nummonthtod=6;; Jul) nummonthtod=7;; Aug) nummonthtod=8;; Sep) nummonthtod=9;; Oct) nummonthtod=10;; Nov) nummonthtod=11;; Dec) nummonthtod=12;; esac # For the first six month of the year the time notation can also # be used for files modified in the last year. if (expr $nummonth \> $nummonthtod) > /dev/null; then year=`expr $year - 1` fi;; *) year=$3;; esac # The result. echo $day $month $year mmm-mode-0.5.1/ChangeLog0000664000175000017500000010517112114105255011723 00000000000000NOTE: This file is not kept up-to-date anymore. 2004-11-18 Alan Shutko * mmm-myghty.el: New mode from Ben Bangert. * mmm-vars.el (mmm-major-mode-preferences): Added Python prefs, also from Ben. * mmm-auto.el (mmm-autoloaded-classes): Merged Ben Bangert's Myghty class. 2004-06-16 Alan Shutko * version.texi: Release 0.4.8. * mmm-vars.el: Release 0.4.8. * mmm-mode.el: Release 0.4.8. * mmm-noweb.el (mmm-syntax-region-list) (mmm-syntax-other-regions, mmm-word-other-regions) (mmm-space-other-regions, mmm-undo-syntax-other-regions): Added from Joe's email. They're here right now, until a better place can be found. * configure.in: Incr version for release. 2004-06-10 Alan Shutko * mmm-class.el (mmm-ify): Change defaults for front-delim and back-delim to nil. 0 was breaking the no-delimiter case in mmm-match-region. 2004-06-02 Alan Shutko * mmm-sample.el (html-js): Support JS version in language attribute. 2004-06-01 Alan Shutko * mmm-vars.el (mmm-save-local-variables): Updated cc-mode local variables. * Makefile.am (lisp_LISP): Removed mmm-php.el, since it doesn't appear to be in CVS. * missing: Updated for automake 1.7.9. 2003-10-18 Alan Shutko * mmm-vars.el (mmm-save-local-variables): Add semantic stuff and c-syntactic-eol. 2003-03-25 Michael A. Shulman * mmm-mode.spec: Added file for building SRPMs, from bishop * autogen.sh: Added file for building from CVS 2003-03-22 Michael A. Shulman * mmm-sample.el (html-php): Added new submode class. (eperl): Corrected, added comment detection. * mmm-cmds.el (mmm-insert-by-key): Added undo collapsing. 2003-03-09 Michael A. Shulman * mmm-vars.el (mmm-set-mode-line): Added support for "buffer mode" display name. * mmm-cmds.el (mmm-insert-by-key): Match and calculate names, and store front and back positions for delimiter overlays. * mmm-mason.el: Added match-name parameter. * mmm-sample.el: Added delimiter-mode and match-name parameters. * mmm-region.el: Restructured current-overlay functions. (mmm-make-region, mmm-make-overlay, mmm-get-face): Create delimiter overlays with modes and faces, add display-name and name parameters, and handle evaporation intelligently. (mmm-front-start, mmm-back-end, etc.): Use delimiter overlays. (mmm-update-current-submode): Delete overlays whose front delimiter has evaporated. * mmm-class.el (mmm-ify, mmm-match-region): Added matching for region names. * mmm-vars.el (mmm-delimiter-mode, mmm-delimiter-face): Added. 2003-03-08 Michael A. Shulman * mmm-region.el (mmm-clear-overlays): Fixed bug so turning mmm mode off now restores primary mode correctly. 2003-03-03 Michael A. Shulman * mmm-noweb.el (mmm-noweb-bind-keys): Implemented a "local to submode class" keymap binding. * mmm-vars.el (mmm-set-mode-line): Used correct name for variable. 2003-03-02 Michael A. Shulman * mmm-mode.el (mmm-mode): Removed ancient docstring, which had references to long-deprecated and removed functions. The info file is now the official user reference. * mmm-region.el (mmm-update-submode-region): Run hooks specified by the region being entered, or the dominant if not. * mmm-vars.el (mmm-primary-mode-entry-hook): Added variable. * mmm-vars.el (mmm-subregion-invalid-placement): Renamed from mmm-subregion-crosses-parents. (mmm-primary-mode-display-name): Added variable. (mmm-set-mode-line): Added function to allow display of specified names outside regions. * mmm-region.el (mmm-valid-submode-region): Corrected algorithm, improved documentation, renamed error. 2003-02-05 Joe Kelsey * mmm-vars.el (mmm-add-to-group): New function mmm-add-to-group adds new private classes to an existing group. * mmm.texinfo (Noweb): Add documentation about noweb mode. * mmm-auto.el (mmm-autoloaded-classes): Add noweb to autoloaded classes. * mmm-noweb.el: Modified chunk naming to give noweb-chunks different names so that they will be indented independently. * mmm-sample.el: Make html-js look for language= or type= attributes because you may have other script types. 2003-01-30 Joe Kelsey * Makefile.am: Add mmm-cweb.el, mmm-php.el and mmm-noweb.el * mmm-noweb.el: Add support for noweb. * mmm-class.el (mmm-ify, mmm-make-region): Add support for setting the NAME property on regions. * mmm-cmds.el (mmm-insert-by-key): Add support for setting the NAME property on inserts. 2002-11-11 Alan Shutko * .cvsignore: Add semantic.cache. * mmm-vars.el (mmm-save-local-variables): Update C variables to save, based on Emacs CVS. * mmm-cweb.el (cweb): Tweaked indentation. Add cweb to the 2001-05-16 Michael Abraham Shulman * mmm-mode.el (mmm-mode-on): Make style variables buffer-local. Continue on all MMM errors. * mmm-vars.el (mmm-save-local-variables): Added all c-modes indentation style variables. * mmm-auto.el, mmm-sample.el: Added `sgml-dtd' submode class from Yann Dirson . 2001-05-15 Michael Abraham Shulman * mmm-auto.el: Added cweb to autoloaded classes. 2001-05-14 Michael Abraham Shulman * mmm-region.el: Passed arguments to `signal'. * mmm-vars.el: Defined new submode placement error conditions. 2001-05-14 Alan Shutko * mmm-cweb.el: New file. * mmm-region.el (mmm-valid-submode-region): New function. (mmm-make-region): Allow nested submodes and put the priority in the overlay. 2001-02-23 Michael Abraham Shulman * configure.in, mmm-mode.el, mmm-vars.el, version.texi: Released 0.4.7 2001-02-18 Alan Shutko * mmm-vars.el (mmm-classes-alist): Document new keywords. * mmm.texinfo (Region Placement): Document the front-match, back-match and end-not-begin keywords. * mmm-class.el (mmm-match-region, mmm-ify): Add front-match & back-match keywords to specify which submatch to treat as the delimiter. Add end-not-begin key. (mmm-match->point): Add front-match and back-match args. 2001-02-12 Alan Shutko * mmm-mason.el (mmm-mason-end-line,mmm-mason-start-line): Use bolp and eolp. 2001-02-03 Michael Abraham Shulman * mmm-mode.el, mmm-region.el, mmm-vars.el: Added `mmm-primary-mode' variable so that `major-mode' can be saved. 2001-01-27 Alan Shutko * mmm.texinfo: Added direntry for automated info installation. 2001-01-26 Alan Shutko * configure.in: Use elisp macros from w3 to check for emacs and lisp dir. * aclocal.m4: Pulled elisp-related checks from the W3 library, so --with-emacs= will work. 2001-01-15 Michael Abraham Shulman * mmm-cmds.el (mmm-insert-by-key): Use match-face and major-mode-preferences. * mmm-sample.el (mmm-here-doc-get-mode): Try each word individually first. * mmm-utils.el (mmm-format-matches): Removed reference to `count' variable. * mmm-sample.el, mmm-univ.el, mmm-utils.el: Allowed language names for preference lookup as "mode names". * mmm-vars.el (mmm-set-major-mode-preferences): Added function. 2001-01-14 Michael Abraham Shulman * mmm-class.el, mmm-utils.el (mmm-format-matches): Changed to allow accessing any subexp, not limited by a numerical value of save-matches. 2001-01-13 Michael Abraham Shulman * mmm-sample.el, mmm-vars.el: Modified CSS to use preferred mode. * mmm-vars.el (mmm-save-local-variables): Added syntax and indentation variables for cc-mode and variants. * mmm-vars.el (mmm-major-mode-preferences): Added check for `jde-mode' for Java code. 2001-01-12 Michael Abraham Shulman * mmm-auto.el: Added ePerl and JSP to autoload. 2001-01-11 Michael Abraham Shulman * mmm-sample.el: Added ePerl submode class. * mmm-mason.el, mmm-sample.el: Modified classes to use preferred mode list. * mmm-vars.el, mmm-region.el: Added alist to keep track of user-preferred major modes. * mmm-mason.el, mmm-rpm.el, mmm-sample.el: Added flags telling which faces to use for which regions. * mmm-class.el, mmm-region.el, mmm-vars.el: Added multiple faces and optional levels of decoration. 2001-01-09 Michael Abraham Shulman * mmm-vars.el (mmm-save-local-variables): Added `parse-sexp-ignore-comments', which seems to fix indentation in php-mode. 2001-01-08 Michael Abraham Shulman * mmm-region.el (mmm-update-mode-info): Hacked so `font-lock-keywords-alist' works. 2001-01-05 Michael Abraham Shulman * mmm.texinfo: Added set-background example for XEmacs. Added info-dir-entry. 2000-09-29 Michael Abraham Shulman * mmm-class.el (mmm-apply-class): Rearranged parameters so faces actually work. 2000-09-18 Michael Abraham Shulman * configure.in, mmm-vars.el, version.texi: Released 0.4.6 2000-09-17 Michael Abraham Shulman * FAQ: Added Q about name capitalization. 2000-09-16 Michael Abraham Shulman * mmm-compat.el (mmm-keywords-used): Added `:private'. 2000-09-12 Michael Abraham Shulman * FAQ: Added file 2000-09-12 Michael Abraham Shulman * Checklist: Added comment about adding files to the distribution. * README: Added comment about installing with multiple emacsen. * Makefile.am: Added FAQ * mmm-mode.el: Created Emacs Lisp Archive Entry 2000-09-05 Michael Abraham Shulman * mmm.texinfo: Set MASON_VERSION. * mmm-cmds.el (mmm-display-insertion-key): Prevented (nthcdr -1 ...); breaks in XEmacs. 2000-08-29 Michael Abraham Shulman * mmm-vars.el (mmm-save-local-variables): Added abbrev-mode variables. * mmm-region.el (mmm-update-mode-info): Tested against `mmm-set-file-name-for-modes'. * mmm-vars.el (mmm-set-file-name-for-modes): Changed to a list for finer control. 2000-08-24 Michael Abraham Shulman * mmm-region.el (mmm-make-region): Explicitly set keyword defaults in &rest parameter. * mmm-class.el (mmm-ify): Explicitly set defaults for keywords in &rest parameter. 2000-08-23 Michael Abraham Shulman * mmm-region.el, mmm-vars.el (mmm-set-buffer-file-name-p): Added to control file name setting. * mmm-vars.el (mmm-save-local-variables): Added `mode-popup-menu' for XEmacs. * mmm-region.el (mmm-update-mode-info): Added some tests for XEmacs 20 to prevent errors and unwanted prompts. Cleared modified flag before killing leftover temporary buffers. 2000-08-21 Michael Abraham Shulman * mmm.texinfo: Added comments on RPM Spec, File Variables, and Here-documents. * mmm-auto.el: Autoloaded `rpm'. * mmm-auto.el: Autoloaded `rpm-sh' submode class from mmm-rpm.el. * mmm-rpm.el: Added file (contributed by Marcus Harnisch). 2000-08-17 Michael Abraham Shulman * mmm-vars.el (mmm-never-modes): Added `forms-mode'. 2000-08-02 Michael Abraham Shulman * configure.in, mmm-vars.el, version.texi: Released 0.4.5. * mmm-compat.el (mmm-set-font-lock-defaults): Made into a macro. * mmm-auto.el: Autoloaded `mmm-ensure-fboundp'. * mmm-region.el (mmm-update-mode-info): Used compatibility wrapper for font-lock defaults. * mmm-compat.el (mmm-set-font-lock-defaults): Added compatibility wrapper function. 2000-08-01 Michael Abraham Shulman * README.Mason, mmm.texinfo: Added comments about `sgml-parent-document'. * mmm-utils.el (mmm-ensure-fboundp): Created function. * mmm-sample.el (mmm-here-doc-get-mode): Extended to recognize names like TEXT_EOF. 2000-07-29 Michael Abraham Shulman * configure.in, mmm-vars.el, version.texi: Released 0.4.4. * mmm-class.el (mmm-get-class-spec): Implemented autoloaded submode classes. * mmm-vars.el (mmm-add-group): Made subclasses of a group private. * mmm-auto.el: Added autoloading of submode classes. * mmm-cmds.el (mmm-ify-by-class): Added completion on autoloaded classes. Excluded private classes from completion. * mmm-vars.el (mmm-classes-alist): Updated docstring for new offset values and include- flags. * mmm-sample.el (here-doc): Updated to use new front-offset values. * mmm-class.el (mmm-ify, mmm-match-region, mmm-match->point): Added new values for front- and back-offset. * mmm-region.el (mmm-make-region): Made sure overlays get the delimiter and sticky properties even if they aren't passed explicitly. 2000-07-26 Michael Abraham Shulman * configure.in: Changed output name from `mmm' to `mmm-mode'. 2000-07-24 Michael Abraham Shulman * mmm-sample.el: Updated file-variables class to handle prefixes. 2000-07-23 Michael Abraham Shulman * mmm-sample.el: Wrote File Variables submode class for the new syntax. 2000-07-21 Michael Abraham Shulman * mmm-cmds.el (mmm-ify-by-class): Added completion on all defined classes. * mmm-sample.el (mmm-here-doc-get-mode): Signaled non-fboundp here-document names. * mmm-univ.el (mmm-univ-get-mode): Signaled error on non-fboundp modes. * mmm-class.el (mmm-match-region, mmm-ify): Caught errors from :match-submode. * mmm-vars.el: Added `mmm-no-matching-submode' error signal. * mmm-sample.el: Allowed here-documents in any mode with :match-submode. Added insertion syntax to here-docs, javascript, and embperl. 2000-07-14 Michael Abraham Shulman * mmm.texinfo, version.texi: Added MASON_VERSION variable to keep track of that. * mmm.texinfo: Wrote about changing key bindings and local variables. Copied info from documentation of `mmm-classes-alist'. 2000-07-13 Michael Abraham Shulman * mmm-vars.el (mmm-run-major-mode-hook): Added `ignore-errors' around each call. * mmm-vars.el (mmm-save-local-variables): Changed `defcustom' to `defvar'. * mmm.texinfo: Wrote about global classes, highlight, mode line, and hooks. * mmm-univ.el: Limited matches to letter/dash strings that are fboundp. 2000-07-12 Michael Abraham Shulman * README.Mason: Added comment about `mmm-global-mode'. 2000-07-12 Michael Abraham Shulman * configure.in, mmm-vars.el: Released 0.4.3. * mmm-univ.el: Changed %[...]% to [%...%] which looks much nicer. * mmm.texinfo: Wrote more about Mason. * mmm-mason.el: Moved commentary code to README.Mason. * Makefile.am: Added README.Mason to EXTRA_DIST. * README.Mason: Created file. 2000-07-11 Michael Abraham Shulman * mmm-region.el (mmm-update-mode-info): Used `mmm-make-temp-buffer'. Put font-lock property directly rather than setting the variable first. * mmm-mode.el (mmm-mode-off): Reset font-lock variables. * mmm-compat.el (mmm-make-temp-buffer): Added as workaround for make-indirect-buffer. * mmm-region.el: (mmm-enable-font-lock, mmm-update-font-lock-buffer, mmm-update-mode-info): Conditioned font-lock usage on mmm-font-lock-available-p. * mmm-compat.el (mmm-font-lock-available-p): Added flag. * mmm-region.el (mmm-update-mode-info): Killed any lingering temporary buffers. * mmm-cmds.el (mmm-insert-by-key): Made inserted regions beg- and end-sticky. * mmm-compat.el (mmm-keywords-used): Added :classes. 2000-06-30 Michael Abraham Shulman * configure.in, mmm-vars.el: Released 0.4.2a. * mmm-region.el: Reordered Inspection and Creation for byte compiler. * mmm-mode.el: Moved mmm-mode variable to mmm-vars.el. * mmm-auto.el: Added some autoloads. * Makefile.am: Added mmm-univ.el. * configure.in, mmm-vars.el: Released 0.4.2. * mmm-auto.el (mmm-mode-on-maybe): Conditioned font-lock updating on mmm-mode. * mmm-region.el: Removed use-local-map advice; no longer necessary (thank goodness!) * mmm-region.el, mmm-auto.el: Fixed font-lock woes (hopefully). * mmm-class.el: Allowed dynamically specified submodes. * mmm-utils.el, mmm-mode.el, mmm-cmds.el: Fixed font-lock woes (hopefully). * mmm.texinfo: Added Embperl. * mmm-vars.el (mmm-global-classes): Added variable controlling global classes. * mmm-univ.el: Created file defining `universal' submode. * mmm-sample.el: Added Embperl. * mmm-utils.el: Added def-edebug-specs. 2000-06-29 Michael Abraham Shulman * mmm-region.el (mmm-fontify-region-list): Saved local variables before moving. * mmm-auto.el (mmm-check-changed-buffers): Checked for live buffer. * mmm-utils.el (mmm-valid-buffer): Checked against noninteractive and hidden buffers. * mmm-auto.el (mmm-check-changed-buffers): Added check against minibuffers. * mmm-vars.el (mmm-never-modes): Added `eshell-mode'. 2000-06-28 Michael Abraham Shulman * NEWS, configure.in, mmm-vars.el: Released 0.4.1. * mmm-region.el (mmm-overlays-in): Added DELIM parameter. (mmm-submode-changes-in): Added strict flags calling overlays-in. 2000-06-27 Michael Abraham Shulman * configure.in, mmm-vars.el: Released 0.4.0. * NEWS, TODO, mmm-auto.el, mmm-region.el, mmm-vars.el, mmm.texinfo: Changed mmm-global-mode to use post-command-hook method rather than stack-walk method. * mmm-region.el: Fixed bug saving variables when creating regions; need to set them first. * mmm-region.el: Added creation-hook, fixed mode-name problem. * mmm-class.el: Added mmm-[get,set]-class-parameters and creation-hook. * mmm-auto.el, mmm-region.el, mmm-vars.el: Fixed bug where font-lock-mode was set to `t' globally, causing global-font-lock-mode to turn it off. 2000-06-26 Michael Abraham Shulman * mmm-region.el: Rewrote local variable functions, added new ones, changed updating, fontification, and region creation functions to handle this. * mmm-mode.el: Added setting and clearing local variables with mode on and off. * mmm-vars.el (mmm-save-local-variables): Added extra parameters for saving type and modes, and updated documentation. Created several variables to save buffer- and region- locals. (mmm-temp-buffer-name): Created variable and changed references. 2000-06-23 Michael Abraham Shulman * mmm-vars.el (mmm-save-local-variable): Added comment-line-start-skip for Fortran. 2000-06-13 Michael Abraham Shulman * mmm.texinfo: Added comment about (require 'mmm-mason). 2000-06-08 Michael Abraham Shulman * configure.in, mmm-vars.el: Released 0.3.10 * mmm-region.el (mmm-overlays-in): Added checks for point-min and point-max for XEmacs. (use-local-map): Added the advice back in. * configure.in, mmm-vars.el: Released 0.3.9. * mmm-region.el (use-local-map): Conditioned advice definition on not XEmacs. 2000-05-28 Michael Abraham Shulman * .cvsignore: Added info file and auxiliary compilation and texinfo files. * .cvsignore: Added configure auxiliary files. * .cvsignore: Ignored Makefile.in, Makefile, and configure. * COPYING, INSTALL, install-sh, mdate-sh, missing, mkinstalldirs, texinfo.tex: Added files required by automake. * mmm.texinfo, elisp-comp, TODO, README, NEWS, ChangeLog, AUTHORS: Added to CVS (formerly not under RCS). 2000-05-24 Michael Abraham Shulman * mmm-auto.el: Pre-added major mode hook to text-mode-hook. 2000-05-19 Michael Abraham Shulman * mmm-vars.el (mmm-version): changed to 0.3.8. 2000-05-18 Michael Abraham Shulman * mmm-region.el: Moved `require's back to top level for byte-compiling. Added dummy definition of `mmm-real-use-local-map' to shut up byte compiler. * mmm-mode.el, mmm-cmds.el, mmm-class.el: Moved `require's back to top level for byte-compiling. * mmm-auto.el: `require'd mmm-vars at top level for byte-compiling. * Makefile.am: Added all the elisp files to EXTRA_DIST, since Automake doesn't see them as sources for the distribution. 2000-05-10 Michael Abraham Shulman * mmm-mason.el: Fixed bug: # is not allowed in symbols. * mmm-mason.el: Changed insertion key of <%doc> to `d' and added insertion of %# comment lines with insertion keys `#' and `3'. * mmm-mason.el: Distinguished between Perl sections and pseudo-Perl sections. The one inserts ; at the beginning for indentation hack, the other doesn't because the Mason syntax doesn't allow it and indentation is generally unnecessary anyway. * mmm-cmds.el: Fixed "sub"-insertion specs like <%perl> under <%TAG> not to insert the interactor string. 2000-05-03 Michael Abraham Shulman * mmm-mason.el: Added dependencies on mmm-compat and mmm-vars. 2000-04-30 Michael Abraham Shulman * configure.in, Makefile.am: New file. * mmm-sample.el, mmm-mode.el, mmm-region.el, mmm-auto.el, mmm-class.el, mmm-cmds.el, mmm-mason.el: Changed (progn (require ...)) to (when t (require ...)) because the first is still "top level" for the byte compiler. * mmm-region.el: Required font-lock and mmm-auto at top level for byte compilation. Moved local maps to come before updating hooks for byte compilation. * mmm-utils.el: Loaded CL at top level for byte-compile. 2000-04-29 Michael Abraham Shulman * mmm-mode.el, mmm-region.el, mmm-sample.el, mmm-auto.el, mmm-class.el, mmm-cmds.el, mmm-mason.el: Put all `require's not needed at compile-time into `progn's so the byte-compiler doesn't load them (not at top level). Only `mmm-compat' and `mmm-utils' need to be loaded at compile-time, since they define macros. 2000-04-27 Michael Abraham Shulman * All: Started using RCS. 2000-04-27 Michael Abraham Shulman * mmm-sample.el (mmm-javascript-mode): Created customization variable to select mode to use for javascript regions. 2000-03-26 Michael Abraham Shulman * mmm-cmds.el (mmm-get-insertion-spec): Insertion keys now have symbolic names, although they have no definition. (mmm-insertion-help): Command added to give help on insertion keys, the way C-h does for command keys. * mmm-vars.el (mmm-get-all-classes): Reversed order, so interactive classes take precedence (for insertion, mainly) over `mmm-classes' which overrides mode/ext classes. 2000-03-24 Michael Abraham Shulman * mmm-vars.el (mmm-command-modifiers, mmm-insert-modifiers): Switched defaults to be the way I think it should be. Users can switch back with `mmm-use-old-command-keys'. * README: Created file giving information on inital installation. * Makefile: Created makefile to compile elisp files and make info file from texinfo file. * mmm-region.el: Gave up on conditional stickiness, since it doesn't work in XEmacs and even FSF Emacs has been being flaky with overlay after-change functions. Detecting ends in global `after-change-functions' will work better anyway. * mmm-cmds.el: Renamed from `mmm-inter.el'. (mmm-end-current-region): Added command, with key binding. * mmm-vars.el (mmm-classes-alist): Documentation updated for unified submode classes. * mmm-class.el (mmm-ify): BEG and END arguments removed; just use FRONT and BACK. * mmm-utils.el (mmm-format-matches): Ignores non-string arguments. * mmm-class.el (mmm-apply-class): Faces supplied for grouping classes now override those on included classes. Parents will do the same thing. * mmm-inter.el: Bound `mmm-parse-block' to C-c % 5 as well. (mmm-reparse-current-region): Added command, with key binding. * mmm-insert.el: Deleted file, merging contents (insert by keystrokes) into `mmm-inter.el'. Auto-detection insert will probably go elsewhere. * mmm-inter.el (mmm-clear-current-region): Uses `mmm-overlay-at' with `all' inclusion type. * mmm-region.el (mmm-overlays-at): Added `all' inclusion type. * mmm-class.el (mmm-apply-class, etc.): Submode classes have been unified--no more 'regexp, 'region, 'group, etc. 2000-03-23 Michael Abraham Shulman * mmm-inter.el (mmm-parse-buffer, mmm-parse-region, mmm-parse-block): Added "Operating...done" messages. * mmm-region.el (mmm-make-region): Allowed caller to add extra keyword arguments to be stored as overlay properties, anticipating new future submode classes. * mmm-update.el (use-local-map): Advised to keep track of changed local maps. * mmm-region.el (mmm-overlays-at): Added inclusion of boundary points based on endpoint stickiness. (mmm-match-front, mmm-match-back): Front and back overlay properties can now be functions rather than regexps, in anticipation of new future submode classes. 2000-03-22 Michael Abraham Shulman * mmm-utils.el (mmm-valid-buffer): Renamed and added checking for "never" modes. * mmm-vars.el (mmm-never-modes): Added, to prevent "temporary shell-mode buffers" and other unnecessariness. * mmm-region.el (mmm-overlays-in): Fixed strictness so it doesn't try to match delimiters of non-mmm overlays. * mmm-update.el (mmm-local-maps-alist): Keep track of changed local maps by buffer and major mode. (mmm-update-submode-region): Update mode info for major mode. * mmm-sample.el: Created file, removing code from `mmm-mode.el'. * mmm-auto.el: Created file, removing code from `mmm-mode.el'. * mason.el: Created file, removing code from `mmm-mode.el'. * mmm-insert.el: Created file, removing code from `mmm-mode.el'. 2000-03-20 Michael Abraham Shulman * mmm-update.el: Created file, removing code from `mmm-mode.el'. * mmm-inter.el: Created file, removing code from `mmm-mode.el'. * mmm-class.el: Created file, removing code from `mmm-mode.el'. * mmm-mode.el (mason): Removed highlight for %doc regions. * mmm-region.el: Created file, removing code from `mmm-mode.el'. * mmm-utils.el: Created file, removing code from `mmm-mode.el'. * mmm-compat.el: Created file, removing code from `mmm-mode.el'. * mmm-vars.el: Created file, removing code from `mmm-mode.el'. * TODO: Created TODO file, removing comments from `mmm-mode.el'. * ChangeLog: Created ChangeLog file and (more or less) ported existing Change Log to official format. 2000-03-19 Michael Abraham Shulman * mmm-mode.el (mmm-global-mode): usurps and extends the role of `mmm-add-find-file-hook'. Other modes can piggyback on our hack by using `mmm-major-mode-hook'. Added :insert class parameters. Classes can now define skeletons to insert submode regions with delimiters based on a keypress. Added `mmm-insert-modifiers' and `mmm-command-modifiers' to configure which keys do what. 2000-03-18 Michael Abraham Shulman * mmm-mode.el: Did a bunch of reorganizing. MMM-ification methods are now submode classes, and what used to be called submode classes are now just a type called :group. User interface is mostly unchanged however. Replaced some gratuitous keywords with normal symbols. Added bells and whistles to :regexp class type, allowing custom "plugin" functions to verify matches and get the delimiter forms, the latter of which aren't used yet, but will be soon. Mason class(es) are now all regexps with a plugin or two. Function class type is not (yet?) ported to the new interface, holding back eval-elisp and htp.p with it. Changed a couple of `eval-and-compile's to `eval-when-compile'. Added special "non-submode" regions, where the major mode holds sway, but no submodes allowed (until parents are implemented). Added %doc in text-mode and %text as a non-submode to Mason, and added %flags, %attr, %method, and %shared tags for Mason classes. These will be new in Mason version 0.82. 2000-03-14 Michael Abraham Shulman * Version 0.3.7a released. * mmm-mode.el: Put `turn-on-font-lock-if-enabled' back in for FSF Emacs. Don't know why I thought I could take it out. 2000------ Michael Abraham Shulman * Version 0.3.7 released. * mmm-mode.el: Set insertion types of markers added to history to coincide with sticky ends of overlays. It's not perfect, but it's better. Renamed mode and submode hook variables to start with `mmm-'. Added "class hooks" run whenever a class is first used in a buffer. Changes for XEmacs compatibility: - Loaded XEmacs overlay emulation package. - Renamed some overlay properties when in XEmacs - Removed `global-font-lock-mode' dependencies. - Added extra parameter to `regexp-opt' in Mason class. Removed "Disclaimers" comment section; I think we have enough testing that it should work on most systems. Reversed order of Change Log so newer changes come first. Changed the default submode highlight to a more neutral gray. Renamed various "start" and "end" parameters to be more uniform. (mmm-ify-by-region): now checks if the region is in bounds. 1999------ Michael Abraham Shulman * Version 0.3.6c released. * mmm-mode.el: Added comment about putting autohandlers and dhandlers in html-mode. 1999------ Michael Abraham Shulman * Version 0.3.6b released. * mmm-mode.el: Added comment about `psgml-mode' thanks to Michael Alan Dorman. 1999------ Michael Abraham Shulman * Version 0.3.6a released. * mmm-mode.el: Loaded CL at compile-time to prevent execution of macro arguments. 1999------ Michael Abraham Shulman * Version 0.3.6 released. * mmm-mode.el: Changes for Emacs 19 compatibility. - Set keyword variables to themselves. - Added hacks for absence of custom.el and regexp-opt. - Added user variable to control use of Perl mode vs CPerl mode. Thanks to Eric A. Zarko for suggestions and testing. 1999------ Michael Abraham Shulman * Version 0.3.5a released. * mmm-mode.el (mmm-ify-by-all): no longer re-fontifies buffers with no submodes. 1999------ Michael Abraham Shulman * Version 0.3.5 released. * mmm-mode.el (mmm-fontify-region): now locally binds `font-lock-beginning-of-syntax-function' to `mmm-beginning-of-syntax' since `font-lock-fontify-block' binds it to nil for some reason. 1999------ Michael Abraham Shulman * Version 0.3.4 released. * mmm-mode.el (mmm-ify-by-class): now fontifies the buffer afterward, like the other interactive MMM-ification functions. Updated a couple doc-strings and prompts. 1999------ Michael Abraham Shulman * Version 0.3.3 released. * mmm-mode.el (mmm-regexp-to-regions, mmm-mason-inline): Changed recursion to iteration, since for long files the recursion runs afoul of `max-lisp-eval-depth'. (mason): Commented on workaround for Mason CPerl mess-ups. Submode overlays now evaporate if they have zero width. (mmm-parse-region): now has a key binding and doesn't refontify the entire buffer. 1999------ Michael Abraham Shulman * Version 0.3.2 released. * mmm-mode.el (mmm-mode-on, mmm-mode-off): are now interactive. Fixed bug in Mason class: %def, %text, and %doc are now ignored as they should be. 1999-11-21 Michael Abraham Shulman * Version 0.3.1 released. * mmm-mode.el (mmm-ify-by-class) now adds to history rather than `mmm-classes'. Fixed :class keyword so it works correctly. (mmm-add-mode-ext-class): Classes associated with major modes or filenames now do The Right Thing when the major mode is changed. However, `mmm-mode-ext-classes-alist' cannot be directly modified. (mmm-mode): Updated documentation to cover 0.3.x changes. 1999-11-21 Michael Abraham Shulman * Version 0.3.0 released. * mmm-mode.el (mmm-ify-by-class): Added interactive prompt. (mmm-version): Function added to display version interactively. Fixed and updated customization definitions. (mmm-mode-ext-classes-alist): added, allowing the automatic association of certain major-modes and/or file extensions with submode classes. Allowed submode lists to contain :class keyword, so one class can invoke another one, if they share submode methods. 1999-11-19 Michael Abraham Shulman * Version 0.2.2a released. * mmm-mode.el: Fixed bug. 1999-11-18 Michael Abraham Shulman * Version 0.2.2 released. * mmm-mode.el (mmm-mason-inline): Replaces the regexps "<% " and "%>" for HTML::Mason submode class. Inline perl regions don't have to begin with a space, but the regexp "<%" matches "<%perl>" as well, which it shouldn't. Added `save-match-data' calls in all searching functions. Removed unnecessary auxiliary functions. 1999-11-16 Michael Abraham Shulman * Version 0.2.1 released. * mmm-mode.el: Fixed font-lock absence, with-temp-message absence, mmm-ifying temp buffer. 1999-11-15 Michael Abraham Shulman * Version 0.2.0 released to HTML::Mason mailing list. * Comment: Although nearly 100% of the code for mmm-mode was written by me, the original inspiration came from mmm.el for XEmacs by Gongquan Chen , so I have continued his version-numbering. 1999-01-12 Gongquan Chen * Version 0.11 released. * mmm.el: Fixed doc-strings and style. Thanks to comments from Jari Aalto 1999-01-11 Gongquan Chen * Version 0.10 released. * mmm.el: Initial release of mmm.el on comp.emacs.xemacs mmm-mode-0.5.1/mmm-myghty.el0000664000175000017500000001401312106045566012603 00000000000000;;; mmm-myghty.el --- MMM submode class for Myghty components ;;; ;; Copyright (C) 2000 by Michael Abraham Shulman ;; Copyright (C) 2004 by Ben Bangert ;; Original Author: Michael Abraham Shulman ;; Based on mmm-mason.el, trivial changes by Ben Bangert ;;{{{ GPL ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;;; I went to the hard (sarcasm) effort of applying two global ;;; search/replaces, and adding a few keywords for additional ;;; blocks that Myghty introduced. Many thanks to Michael for writing ;;; the mmm-mason without which I would never have found the time ;;; to patch up for Myghty. ;;; Code: (require 'mmm-compat) (require 'mmm-vars) (require 'mmm-auto) ;;{{{ Python Tags (defvar mmm-myghty-python-tags '("python" "init" "cleanup" "once" "filter" "shared" "global" "threadlocal" "requestlocal" "python_init" "python_cleanup" "python_once" "python_filter")) (defvar mmm-myghty-pseudo-python-tags '("args" "python_args" "attr" "flags")) (defvar mmm-myghty-non-python-tags '("doc" "python_doc" "text" "python_text" "def" "python_def" "method")) (defvar mmm-myghty-python-tags-regexp (concat "<%" (mmm-regexp-opt mmm-myghty-python-tags t) ">") "Matches tags beginning Myghty sections containing Python code. Saves the name of the tag matched.") (defvar mmm-myghty-pseudo-python-tags-regexp (concat "<%" (mmm-regexp-opt mmm-myghty-pseudo-python-tags t) ">") "Match tags beginning Myghty sections that look like Python but aren't. Saves the name of the tag matched.") (defvar mmm-myghty-tag-names-regexp (regexp-opt (append mmm-myghty-python-tags mmm-myghty-non-python-tags) t) "Matches any Myghty tag name after the \"<%\". Used to verify that a \"<%\" sequence starts an inline section.") (defun mmm-myghty-verify-inline () (not (looking-at mmm-myghty-tag-names-regexp))) ;;}}} ;;{{{ Add Classes (mmm-add-group 'myghty `((myghty-text :submode nil :front "<%text>" :back "" :insert ((?t myghty-<%text> nil @ "<%text>" @ "\n" _ "\n" @ "" @))) (myghty-doc :submode text-mode :face mmm-comment-submode-face :front "<%doc>" :back "" :face nil :insert ((?d myghty-<%doc> nil @ "<%doc>" @ "\n" _ "\n" @ "" @))) (myghty-python :submode python :match-face (("<%python>" . mmm-code-submode-face) ("<%init>" . mmm-init-submode-face) ("<%cleanup>" . mmm-cleanup-submode-face) ("<%once>" . mmm-init-submode-face) ("<%global>" . mmm-init-submode-face) ("<%filter>" . mmm-special-submode-face) ("<%shared>" . mmm-init-submode-face) ("<%threadlocal>" . mmm-init-submode-face) ("<%requestlocal>" . mmm-init-submode-face)) :front ,mmm-myghty-python-tags-regexp :back "" :save-matches 1 :match-name "~1" :save-name 1 :insert ((?, myghty-<%TAG> "Python section: " @ "<%" str ">" @ ";\n" _ "\n" @ "" @) (?< myghty-<%TAG> ?, . nil) (?p myghty-<%python> ?, . "python") (?i myghty-<%init> ?, . "init") (?c myghty-<%cleanup> ?, . "cleanup") (?o myghty-<%once> ?, . "once") (?g myghty-<%global> ?, . "global") (?t myghty-<%threadlocal> ?, . "threadlocal") (?e myghty-<%requestlocal> ?, . "requestlocal") (?l myghty-<%filter> ?, . "filter") (?s myghty-<%shared> ?, . "shared"))) (myghty-pseudo-python :submode python :face mmm-declaration-submode-face :front ,mmm-myghty-pseudo-python-tags-regexp :back "" :save-matches 1 :insert ((?. myghty-pseudo-<%TAG> "Pseudo-python section: " @ "<%" str ">" @ "\n" _ "\n" @ "" @) (?> myghty-pseudo-<%TAG> ?, . nil) (?a myghty-<%args> ?. . "args") (?f myghty-<%flags> ?. . "flags") (?r myghty-<%attr> ?. . "attr"))) (myghty-inline :submode python :face mmm-output-submode-face :front "<%" :front-verify mmm-myghty-verify-inline :back "%>" :insert ((?% myghty-<%-%> nil @ "<%" @ " " _ " " @ "%>" @) (?5 myghty-<%-%> ?% . nil))) (myghty-call :submode python :face mmm-special-submode-face :front "<&" :back "&>" :insert ((?& myghty-<&-&> nil @ "<&" @ " " _ " " @ "&>" @) (?7 myghty-<&-&> ?% . nil))) (myghty-one-line-comment :submode text-mode :face mmm-comment-submode-face :front "^%#" :back "\n" :insert ((?# myghty-%-comment nil (mmm-myghty-start-line) @ "%" @ "# " _ @ '(mmm-myghty-end-line) "\n" @) (?3 myghty-%-comment ?# . nil))) (myghty-one-line :submode python :face mmm-code-submode-face :front "^%" :back "\n" :insert ((return myghty-%-line nil (mmm-myghty-start-line) @ "%" @ " " _ @ '(mmm-myghty-end-line) "\n" @))))) ;;}}} ;;{{{ One-line Sections (defun mmm-myghty-start-line () (if (bolp) "" "\n")) (defun mmm-myghty-end-line () (if (eolp) (delete-char 1))) ;;}}} ;;{{{ Set Mode Line (defun mmm-myghty-set-mode-line () (setq mmm-buffer-mode-display-name "Myghty")) (add-hook 'mmm-myghty-class-hook 'mmm-myghty-set-mode-line) ;;}}} (provide 'mmm-myghty) ;;; mmm-myghty.el ends here mmm-mode-0.5.1/aclocal.m40000664000175000017500000005731112114107235012013 00000000000000# generated automatically by aclocal 1.11.6 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, # Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software # Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.11' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.11.6], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.11.6])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2008, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 16 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.62])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl dnl The `parallel-tests' driver may need to know about EXEEXT, so add the dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, # Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, # 2006 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 10 # AM_PATH_LISPDIR # --------------- AC_DEFUN([AM_PATH_LISPDIR], [AC_PREREQ([2.60])dnl # If set to t, that means we are running in a shell under Emacs. # If you have an Emacs named "t", then use the full path. test x"$EMACS" = xt && EMACS= AC_CHECK_PROGS([EMACS], [emacs xemacs], [no]) AC_ARG_VAR([EMACS], [the Emacs editor command]) AC_ARG_VAR([EMACSLOADPATH], [the Emacs library search path]) AC_ARG_WITH([lispdir], [ --with-lispdir override the default lisp directory], [ lispdir="$withval" AC_MSG_CHECKING([where .elc files should go]) AC_MSG_RESULT([$lispdir])], [ AC_CACHE_CHECK([where .elc files should go], [am_cv_lispdir], [ if test $EMACS != "no"; then if test x${lispdir+set} != xset; then # If $EMACS isn't GNU Emacs or XEmacs, this can blow up pretty badly # Some emacsen will start up in interactive mode, requiring C-x C-c to exit, # which is non-obvious for non-emacs users. # Redirecting /dev/null should help a bit; pity we can't detect "broken" # emacsen earlier and avoid running this altogether. AC_RUN_LOG([$EMACS -batch -q -eval '(while load-path (princ (concat (car load-path) "\n")) (setq load-path (cdr load-path)))' conftest.out]) am_cv_lispdir=`sed -n \ -e 's,/$,,' \ -e '/.*\/lib\/x*emacs\/site-lisp$/{s,.*/lib/\(x*emacs/site-lisp\)$,${libdir}/\1,;p;q;}' \ -e '/.*\/share\/x*emacs\/site-lisp$/{s,.*/share/\(x*emacs/site-lisp\),${datarootdir}/\1,;p;q;}' \ conftest.out` rm conftest.out fi fi test -z "$am_cv_lispdir" && am_cv_lispdir='${datadir}/emacs/site-lisp' ]) lispdir="$am_cv_lispdir" ]) AC_SUBST([lispdir]) ])# AM_PATH_LISPDIR AU_DEFUN([ud_PATH_LISPDIR], [AM_PATH_LISPDIR]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 6 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, # Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # AM_PROG_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software # Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 3 # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([acinclude.m4]) mmm-mode-0.5.1/mmm-erb.el0000664000175000017500000002210112106327535012026 00000000000000;;; mmm-erb.el --- ERB templates editing support ;; Copyright (C) 2012, 2013 by Dmitry Gutov ;; Author: Dmitry Gutov ;;{{{ GPL ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file contains definitions of ERB and EJS submode classes, and well as ;; support functions for proper indentation. ;; Usage: ;; (require 'mmm-auto) ;; (setq mmm-global-mode 'auto) ;; (mmm-add-mode-ext-class 'html-erb-mode "\\.html\\.erb\\'" 'erb) ;; (mmm-add-mode-ext-class 'html-erb-mode "\\.jst\\.ejs\\'" 'ejs) ;; (mmm-add-mode-ext-class 'html-erb-mode nil 'html-js) ;; (mmm-add-mode-ext-class 'html-erb-mode nil 'html-css) ;; (add-to-list 'auto-mode-alist '("\\.html\\.erb\\'" . html-erb-mode)) ;; (add-to-list 'auto-mode-alist '("\\.jst\\.ejs\\'" . html-erb-mode)) ;; Optional settings: ;; (setq mmm-submode-decoration-level 2 ;; mmm-parse-when-idle t) ;; nXML as primary mode (supports only JS and CSS subregions): ;; (mmm-add-mode-ext-class 'nxml-web-mode nil 'html-js) ;; (mmm-add-mode-ext-class 'nxml-web-mode nil 'html-css) ;; (add-to-list 'auto-mode-alist '("\\.xhtml\\'" . nxml-web-mode)) ;;; Code: (require 'sgml-mode) (eval-when-compile (require 'cl)) (require 'mmm-vars) (require 'mmm-region) (mmm-add-classes '((erb :submode ruby-mode :front "<%[#=]?" :back "-?%>" :match-face (("<%#" . mmm-comment-submode-face) ("<%=" . mmm-output-submode-face) ("<%" . mmm-code-submode-face)) :insert ((?% erb-code nil @ "<%" @ " " _ " " @ "%>" @) (?# erb-comment nil @ "<%#" @ " " _ " " @ "%>" @) (?= erb-expression nil @ "<%=" @ " " _ " " @ "%>" @)) :creation-hook mmm-erb-mark-as-special) (ejs :submode js-mode :front "<%[#=]?" :back "-?%>" :match-face (("<%#" . mmm-comment-submode-face) ("<%=" . mmm-output-submode-face) ("<%" . mmm-code-submode-face)) :insert ((?% ejs-code nil @ "<%" @ " " _ " " @ "%>" @) (?# ejs-comment nil @ "<%#" @ " " _ " " @ "%>" @) (?= ejs-expression nil @ "<%=" @ " " _ " " @ "%>" @)) :creation-hook mmm-erb-mark-as-special))) ;;;###autoload (define-derived-mode html-erb-mode html-mode "ERB-HTML" (setq sgml-unclosed-tags nil) ; Simplifies indentation logic. (set (make-local-variable 'mmm-indent-line-function) 'mmm-erb-indent-line)) (defun mmm-erb-mark-as-special () "Hook function to run in ERB and EJS tag regions." (overlay-put mmm-current-overlay 'mmm-special-tag t)) (defun mmm-erb-indent-line () "Indent the current line intelligently." (interactive) (let ((offset (- (current-column) (current-indentation)))) (back-to-indentation) (mmm-update-submode-region) (if (and mmm-current-overlay mmm-current-submode (< (overlay-start mmm-current-overlay) (point-at-bol))) ;; Region starts before the current line (and contains indentation). ;; If it starts on the current line, then either first part of the line ;; is in primary mode, or we're on the first line of a script or style ;; tag contents. In the latter case, better to also indent it according ;; to the primary mode (as text): `js-indent-line' ignores narrowing, ;; gets confused by the angle bracket on the previous line and thus ;; breaks our "top level" heuristic. (mmm-erb-indent-line-submode) (mmm-erb-indent-line-primary)) (when (> offset 0) (forward-char offset)))) (defun mmm-erb-indent-line-submode () "Indent line within a submode." (let (added-whitespace) (if (<= (overlay-end mmm-current-overlay) (save-excursion (back-to-indentation) (point))) ;; We're at a closing tag. (mmm-erb-indent-to-region-start) (save-restriction (save-excursion (goto-char (overlay-start mmm-current-overlay)) (when (not (looking-at "^\\|\\s-*$")) ;; Submode region has text on the same line as the opening tag, ;; pad it with whitespace to make the following lines line up. (setq added-whitespace (current-column)) (insert-char ?\s added-whitespace))) (narrow-to-region (overlay-start mmm-current-overlay) (overlay-end mmm-current-overlay)) (funcall (mmm-erb-orig-indent-function mmm-current-submode)) (when added-whitespace ;; Remove the padding. (save-excursion (goto-char (overlay-start mmm-current-overlay)) (delete-char added-whitespace)))) ;; If submode indent function moved us to bol, ;; we're on the top level, indent according to the primary mode. (when (zerop (current-indentation)) (mmm-erb-indent-to-region-start (mmm-erb-indent-offset mmm-primary-mode)))))) (defun mmm-erb-indent-to-region-start (&optional additional-offset) "Indent line to match start of region, possibly adding ADDITIONAL-OFFSET." (let ((indent (current-indentation))) (indent-line-to (save-excursion (goto-char (1- (overlay-start mmm-current-overlay))) (+ (current-indentation) (or additional-offset 0)))))) (defun mmm-erb-indent-line-primary () "Indent line in primary mode." (let* ((here (point)) ;; Go before previous line's tag. (start (progn (forward-line -1) (back-to-indentation) (let ((lcon (sgml-lexical-context))) (when (eq (car lcon) 'tag) ;; Tag spreads several lines. (goto-char (cdr lcon)) (back-to-indentation))) (point))) (regions (mmm-regions-in start here)) (n 0)) ;; Collect indent modifier depending on type of tags. (loop for region in regions for type = (mmm-erb-scan-region region) when type do (if (eq type 'close) (when (plusp n) (decf n)) (incf n (if (eq type 'close) 0 1)))) (let ((eol (progn (goto-char here) (end-of-line 1) (point)))) ;; Look for "else" and "end" instructions to adjust modifier. ;; If a block start instruction comes first, abort. (loop for region in (mmm-regions-in here eol) for type = (mmm-erb-scan-region region) until (eq type 'open) when (memq type '(middle close)) do (decf n))) (goto-char here) (funcall (mmm-erb-orig-indent-function mmm-primary-mode)) (let* ((indent (current-indentation)) (indent-step (mmm-erb-indent-offset mmm-primary-mode))) (indent-line-to (+ indent (if n (* indent-step n) 0)))))) (defun mmm-erb-scan-region (region) (when region ; Can be nil if a line is empty, for example. (destructuring-bind (submode beg end ovl) region (let ((scan-fn (plist-get '(ruby-mode mmm-erb-scan-erb js-mode mmm-erb-scan-ejs) submode))) (and scan-fn (overlay-get ovl 'mmm-special-tag) (save-excursion (goto-char beg) (skip-syntax-forward "-") (funcall scan-fn end))))))) (defconst mmm-erb-ruby-close-re "\\\\|}" "Regexp to match the end of a Ruby block.") (defun mmm-erb-scan-erb (limit) (cond ((looking-at "\\(?:if\\|unless\\|for\\|while\\)\\b") 'open) ((looking-at "\\(?:else\\|elsif\\)\\b") 'middle) ((looking-at mmm-erb-ruby-close-re) 'close) ((and (re-search-forward (concat "\\(?: +do +\\| *{ *\\)" "\\(?:|[A-Za-z0-9_, ]*|\\)? *") limit t) (not (re-search-forward mmm-erb-ruby-close-re limit t))) 'open))) (defun mmm-erb-scan-ejs (limit) (cond ((looking-at "\\(?:if\\|for\\|while\\)\\b") 'open) ((looking-at "} *else\\b") 'middle) ((looking-at "}") 'close) ((re-search-forward " *{ *" limit t) 'open))) (defun mmm-erb-orig-indent-function (mode) (get mode 'mmm-indent-line-function)) (defvar mmm-erb-offset-var-alist '((html-erb-mode . sgml-basic-offset) (nxml-web-mode . nxml-child-indent))) (defun mmm-erb-indent-offset (mode) (let ((name (cdr (assoc mode mmm-erb-offset-var-alist)))) (when name (symbol-value name)))) ;;;###autoload (define-derived-mode nxml-web-mode nxml-mode "nXML-Web" (set (make-local-variable 'mmm-indent-line-function) 'mmm-erb-indent-line)) (provide 'mmm-erb) ;;; mmm-erb.el ends here mmm-mode-0.5.1/mmm-cmds.el0000664000175000017500000003754512106045373012223 00000000000000;;; mmm-cmds.el --- MMM Mode interactive commands and keymap ;; Copyright (C) 2000 by Michael Abraham Shulman ;; Author: Michael Abraham Shulman ;;{{{ GPL ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;}}} ;;; Commentary: ;; This file contains the interactive commands for MMM Mode. ;;; Code: (require 'cl) (require 'font-lock) (require 'mmm-compat) (require 'mmm-vars) (require 'mmm-class) ;; APPLYING CLASSES ;;{{{ Applying Predefined Classes (defun mmm-ify-by-class (class) "Add submode regions according to an existing submode class." (interactive (list (intern (completing-read "Submode Class: " (remove-duplicates (mapcar #'(lambda (spec) (list (symbol-name (car spec)))) (append (remove-if #'(lambda (spec) (plist-get (cdr spec) :private)) mmm-classes-alist) (remove-if #'caddr mmm-autoloaded-classes))) :test #'equal) nil t)))) (unless (eq class (intern "")) (mmm-apply-class class) (mmm-add-to-history class) (mmm-update-font-lock-buffer))) ;;}}} ;;{{{ Applying by the Region (defun mmm-ify-region (submode front back) "Add a submode region for SUBMODE coinciding with current region." (interactive "aSubmode: \nr") (mmm-ify :submode submode :front front :back back) (setq front (mmm-make-marker front t nil) back (mmm-make-marker back nil nil)) (mmm-add-to-history `(:submode ,submode :front ,front :back ,back)) (mmm-enable-font-lock submode)) ;;}}} ;;{{{ Applying Simple Regexps (defun mmm-ify-by-regexp (submode front front-offset back back-offset save-matches) "Add SUBMODE regions to the buffer delimited by FRONT and BACK. With prefix argument, prompts for all additional keywords arguments. See `mmm-classes-alist'." (interactive "aSubmode: sFront Regexp: nOffset from Front Regexp: sBack Regexp: nOffset from Back Regexp: nNumber of matched substrings to save: ") (let ((args (mmm-save-keywords submode front back front-offset back-offset save-matches))) (apply #'mmm-ify args) (mmm-add-to-history args)) (mmm-enable-font-lock submode)) ;;}}} ;; EDITING WITH REGIONS ;;{{{ Re-parsing Areas (defun mmm-parse-buffer () "Re-apply all applicable submode classes to current buffer. Clears all current submode regions, reapplies all past interactive mmm-ification, and applies `mmm-classes' and mode-extension classes." (interactive) (message "MMM-ifying buffer...") (mmm-apply-all) (message "MMM-ifying buffer...done")) (defun mmm-parse-region (start stop) "Re-apply all applicable submode classes between START and STOP. Clears all current submode regions, reapplies all past interactive mmm-ification, and applies `mmm-classes' and mode-extension classes." (interactive "r") (message "MMM-ifying region...") (mmm-apply-all :start start :stop stop) (message "MMM-ifying region...done")) (defun mmm-parse-block (&optional lines) "Re-parse LINES lines before and after point \(default 1). Clears all current submode regions, reapplies all past interactive mmm-ification, and applies `mmm-classes' and mode-extension classes. This command is intended for use when you have just typed what should be the delimiters of a submode region and you want to create the region. However, you may want to look into the various types of delimiter auto-insertion that MMM Mode provides. See, for example, `mmm-insert-region'." (interactive "p") (message "MMM-ifying block...") (destructuring-bind (start stop) (mmm-get-block lines) (when (< start stop) (mmm-apply-all :start start :stop stop))) (message "MMM-ifying block...done")) (defun mmm-get-block (lines) (let ((inhibit-point-motion-hooks t)) (list (save-excursion (forward-line (- lines)) (beginning-of-line) (point)) (save-excursion (forward-line lines) (end-of-line) (point))))) ;;}}} ;;{{{ Reparse Current Region (defun mmm-reparse-current-region () "Clear and reparse the area of the current submode region. Use this command if a submode region's boundaries have become wrong." (interactive) (let ((ovl (mmm-overlay-at (point) 'all))) (when ovl (let ((beg (save-excursion (goto-char (mmm-front-start ovl)) (forward-line -1) (point))) (end (save-excursion (goto-char (mmm-back-end ovl)) (forward-line 1) (point)))) (mmm-parse-region beg end))))) ;;}}} ;;{{{ Clear Submode Regions ;; See also `mmm-clear-history' which is interactive. (defun mmm-clear-current-region () "Deletes the submode region point is currently in, if any." (interactive) (delete-overlay (mmm-overlay-at (point) 'all))) (defun mmm-clear-regions (start stop) "Deletes all submode regions from START to STOP." (interactive "r") (mmm-clear-overlays start stop)) (defun mmm-clear-all-regions () "Deletes all submode regions in the current buffer." (interactive) (mmm-clear-overlays)) ;;}}} ;;{{{ End Current Region (defun* mmm-end-current-region (&optional arg) "End current submode region. If ARG is nil, end it at the most appropriate place, usually its current back boundary. If ARG is non-nil, end it at point. If the current region is correctly bounded, the first does nothing, but the second deletes that delimiter as well. If the region's BACK property is a string, it is inserted as above and the overlay moved if necessary. If it is a function, it is called with two arguments--the overlay, and \(if ARG 'middle t)--and must do the entire job of this function." (interactive "P") (let ((ovl (mmm-overlay-at))) (when ovl (combine-after-change-calls (save-match-data (save-excursion (when (mmm-match-back ovl) (if arg (replace-match "") (return-from mmm-end-current-region))))) (let ((back (overlay-get ovl 'back))) (cond ((stringp back) (save-excursion (unless arg (goto-char (overlay-end ovl))) (save-excursion (insert back)) (move-overlay ovl (overlay-start ovl) (point)))) ((functionp back) (funcall back ovl (if arg 'middle t)))))) (mmm-refontify-maybe (save-excursion (forward-line -1) (point)) (save-excursion (forward-line 1) (point)))))) ;;}}} ;;{{{ Narrow to Region (defun mmm-narrow-to-submode-region (&optional pos) "Narrow to the submode region at point." (interactive) ;; Probably don't use mmm-current-overlay here, because this is ;; sometimes called from inside messy functions. (let ((ovl (mmm-overlay-at pos))) (when ovl (narrow-to-region (overlay-start ovl) (overlay-end ovl))))) ;; The inverse command is `widen', usually on `C-x n w' ;;}}} ;; INSERTING REGIONS ;;{{{ Insert regions by keystroke ;; This is the "default" binding in the MMM Mode keymap. Keys defined ;; by classes should be control keys, to avoid conflicts with MMM ;; commands. (defun mmm-insert-region (arg) "Insert a submode region based on last character in invoking keys. Keystrokes after `mmm-mode-prefix-key' which are not bound to an MMM Mode command \(see `mmm-command-modifiers') are passed on to this function. If they have the modifiers `mmm-insert-modifiers', then they are looked up, sans those modifiers, in all current submode classes to find an insert skeleton. For example, in Mason, `p' \(with appropriate prefix and modifiers) will insert a <%perl>... region." (interactive "P") (let* ((seq (this-command-keys)) (event (aref seq (1- (length seq)))) (mods (event-modifiers event)) (key (mmm-event-key event))) (if (subsetp mmm-insert-modifiers mods) (mmm-insert-by-key (append (set-difference mods mmm-insert-modifiers) key) arg)))) (defun mmm-insert-by-key (key &optional arg) "Insert a submode region based on event KEY. Inspects all the classes of the current buffer to find a matching :insert key sequence. See `mmm-classes-alist'. ARG, if present, is passed on to `skeleton-proxy-new' to control wrapping. KEY must be a list \(MODIFIERS... . BASIC-KEY) where MODIFIERS are symbols such as shift, control, etc. and BASIC-KEY is a character code or a symbol such as tab, return, etc. Note that if there are no MODIFIERS, the dotted list becomes simply BASIC-KEY." (multiple-value-bind (class skel str) (mmm-get-insertion-spec key) (when skel (let ((after-change-functions nil) (old-undo buffer-undo-list) undo) ;; XEmacs' skeleton doesn't manage positions by itself, so we ;; have to do it. (if mmm-xemacs (setq skeleton-positions nil)) (skeleton-proxy-new skel str arg) (destructuring-bind (back end beg front) skeleton-positions ;; TODO: Find a way to trap invalid-parent signals from ;; make-region and undo the skeleton insertion. (let ((match-submode (plist-get class :match-submode)) (match-face (plist-get class :match-face)) (match-name (plist-get class :match-name)) (front-form (regexp-quote (buffer-substring front beg))) (back-form (regexp-quote (buffer-substring end back))) submode face name) (setq submode (mmm-modename->function (if match-submode (mmm-save-all (funcall match-submode front-form)) (plist-get class :submode)))) (setq face (cond ((functionp match-face) (mmm-save-all (funcall match-face front-form))) (match-face (cdr (assoc front-form match-face))) (t (plist-get class :face)))) (setq name (cond ((plist-get class :skel-name) ;; Optimize the name to the user-supplied str ;; if we are so instructed. str) ;; Call it if it is a function ((functionp match-name) (mmm-save-all (funcall match-name front-form))) ;; Now we know it's a string, does it need to ;; be formatted? ((plist-get class :save-name) ;; Yes. Haven't done a match before, so ;; match the front regexp against the given ;; form to format the string (string-match (plist-get class :front) front-form) (mmm-format-matches match-name front-form)) (t ;; No, just use it as-is match-name))) (mmm-make-region submode beg end :face face :name name :front front :back back :match-front front-form :match-back back-form :evaporation 'front ;;; :beg-sticky (plist-get class :beg-sticky) ;;; :end-sticky (plist-get class :end-sticky) :beg-sticky t :end-sticky t :creation-hook (plist-get class :creation-hook)) (mmm-enable-font-lock submode))) ;; Now get rid of intermediate undo boundaries, so that the entire ;; insertion can be undone as one action. This should really be ;; skeleton's job, but it doesn't do it. (setq undo buffer-undo-list) (while (not (eq (cdr undo) old-undo)) (when (eq (cadr undo) nil) (setcdr undo (cddr undo))) (setq undo (cdr undo))))))) (defun mmm-get-insertion-spec (key &optional classlist) "Get the insertion info for KEY from all classes in CLASSLIST. Return \(CLASS SKEL STR) where CLASS is the class spec a match was found in, SKEL is the skeleton to insert, and STR is the argument. CLASSLIST defaults to the return value of `mmm-get-all-classes', including global classes." (loop for classname in (or classlist (mmm-get-all-classes t)) for class = (mmm-get-class-spec classname) for inserts = (plist-get class :insert) for skel = (cddr (assoc key inserts)) with str ;; If SKEL is a dotted pair, it means call another key's ;; insertion spec with an argument. unless (consp (cdr skel)) do (setq str (cdr skel) skel (cddr (assoc (car skel) inserts))) if skel return (list class skel str) ;; If we have a group class, recurse. if (plist-get class :classes) if (mmm-get-insertion-spec key it) return it)) ;;}}} ;;{{{ Help on Insertion (defun mmm-insertion-help () "Display help on currently available MMM insertion commands." (interactive) (with-output-to-temp-buffer "*Help*" (princ "Available MMM Mode Insertion Commands:\n") (princ "Key Inserts\n") (princ "--- -------\n\n") (mapcar #'mmm-display-insertion-key (mmm-get-all-insertion-keys)))) (defun mmm-display-insertion-key (spec) "Print an insertion binding to standard output. SPEC should be \(KEY NAME ...) where KEY is an insertion key and NAME is a symbol naming the insertion." (let* ((str (make-string 16 ?\ )) ;; This gets us a dotted list, because of the way insertion ;; keys are specified. (key (append mmm-insert-modifiers (car spec))) (lastkey (nthcdr (max (1- (safe-length key)) 0) key))) ;; Now we make it a true list (if (consp key) (setcdr lastkey (list (cdr lastkey))) (setq key (list key))) ;; Get the spacing right (store-substring str 0 (key-description (apply #'vector (append mmm-mode-prefix-key (list key))))) (princ str) ;; Now print the binding symbol (princ (cadr spec)) (princ "\n"))) (defun mmm-get-all-insertion-keys (&optional classlist) "Return an alist of all currently available insertion keys. Elements look like \(KEY NAME ...) where KEY is an insertion key and NAME is a symbol naming the insertion." (remove-duplicates (loop for classname in (or classlist (mmm-get-all-classes t)) for class = (mmm-get-class-spec classname) append (plist-get class :insert) into keys ;; If we have a group class, recurse. if (plist-get class :classes) do (setq keys (append keys (mmm-get-all-insertion-keys it))) finally return keys) :test #'equal :key #'(lambda (x) (cons (car x) (cadr x))) :from-end t)) ;;}}} ;;{{{ Auto Insertion (copied from interactive session);-COM- ;-COM- ;-COM-;; Don't use `mmm-ify-region' of course. And rather than having ;-COM-;; classes define their own functions, we should have them pass a ;-COM-;; skeleton as an attribute. Then our insert function can turn off ;-COM-;; after-change hooks and add the submode region afterward. ;-COM- ;-COM-(define-skeleton mmm-see-inline ;-COM- "" nil ;-COM- -1 @ " " _ " " @ "%>" ;-COM- '(apply #'mmm-ify-region 'cperl-mode (reverse skeleton-positions))) ;-COM- ;-COM-(define-skeleton mmm-see-other ;-COM- "" nil ;-COM- @ ";\n" _ "\n" @ "<%/" str ">" ;-COM- '(apply #'mmm-ify-region 'cperl-mode (reverse skeleton-positions))) ;-COM- ;-COM-(make-local-hook 'after-change-functions) ;-COM-(add-hook 'after-change-functions 'mmm-detect t) ;-COM- ;-COM-(defun mmm-detect (beg end length) ;-COM- (when (mmm-looking-back-at "<% ") ;-COM- (mmm-see-inline)) ;-COM- (when (mmm-looking-back-at "<%\\(\\w+\\)>") ;-COM- (mmm-see-other (match-string 1)))) ;-COM- ;;}}} (provide 'mmm-cmds) ;;; mmm-cmds.el ends here mmm-mode-0.5.1/COPYING0000664000175000017500000004311012043063215011176 00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. mmm-mode-0.5.1/mmm.texinfo0000664000175000017500000025664512043063215012352 00000000000000\input texinfo @c %**start of header @setfilename mmm.info @settitle MMM Mode Manual @c %**end of header @syncodeindex vr fn @set MASON_VERSION 0.896 @dircategory GNU Emacs Lisp @direntry * MMM-Mode: (mmm). Multiple Major Modes for Emacs @end direntry @include version.texi @ifinfo This is edition @value{EDITION} of the MMM Mode Manual, last updated @value{UPDATED}. It documents version @value{VERSION} of MMM Mode. Copyright 2000 Michael Abraham Shulman. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. @ignore Permission is granted to process this file through TeX and print the results, provided the printed document carries a copying permission notice identical to this one except for the removal of this paragraph (this paragraph not being relevant to the printed manual). @end ignore Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the sections entitled ``Copying'' and ``GNU General Public License'' are included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. @end ifinfo @titlepage @title MMM Mode Manual @subtitle Multiple Major Modes for Emacs @subtitle Edition @value{EDITION} @subtitle @value{UPDATED} @author Michael Abraham Shulman @page @vskip 0pt plus 1filll Copyright @copyright{} 2000 Michael Abraham Shulman. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the sections entitled ``Copying'' and ``GNU General Public License'' are included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. @end titlepage @ifinfo @node Top, Overview, (dir), (dir) @top MMM Mode MMM Mode is a minor mode for Emacs which allows Multiple Major Modes to coexist in a single buffer. This is edition @value{EDITION} of the MMM Mode Manual, last updated @value{UPDATED}, which documents version @value{VERSION} of MMM Mode. @end ifinfo @menu * Overview:: An overview and introduction to MMM Mode. * Basics:: The basics of how to use it. * Customizing:: Customizing how it works to your needs. * Supplied Classes:: The supplied submode classes. * Writing Classes:: Writing your own submode classes. * Indices:: Just that. @detailmenu --- The Detailed Node Listing --- Overview of MMM Mode * Basic Concepts:: A simple explanation of how it works. * Installation:: How to install MMM Mode. * Quick Start:: Getting started using MMM Mode quickly. MMM Mode Basics * MMM Minor Mode:: The Emacs minor mode that manages it all. * Submode Classes:: What they are and how to use them. * Selecting Classes:: How MMM Mode knows what classes to use. * Insertion:: Inserting new submode regions automatically. * Re-parsing:: Re-scanning for submode regions. * Interactive:: Adding submode regions manually. * Global Mode:: Turning MMM Mode on automatically. The MMM Minor Mode * Enabling MMM Mode:: Turning MMM Mode on and off. * MMM Mode Keys:: Default key bindings in MMM Mode. How MMM Mode selects submode classes * File Classes:: Classes for a single file. * Mode-Ext Classes:: Classes for a given mode or extension. * Global Classes:: Classes for all MMM Mode buffers. MMM Global Mode * Major Mode Hook:: Using MMM's Major Mode Hook Customizing MMM Mode * Region Coloring:: Changing or removing background colors. * Preferred Modes:: Choosing which major modes to use. * Mode Line:: What is displayed in the mode line. * Key Bindings:: Customizing the MMM Mode key bindings. * Local Variables:: What local variables are saved for submodes. * Changing Classes:: Changing the supplied submode classes. * Hooks:: How to make MMM Mode run your code. Supplied Submode Classes * Mason:: Mason server-side Perl in HTML. * File Variables:: Elisp code in File Variables. * Here-documents:: Code in shell and Perl here-documents. * Javascript:: Javascript embedded in HTML. * Embedded CSS:: CSS Styles embedded in HTML. * Embperl:: Another syntax for Perl in HTML. * ePerl:: A general Perl-embedding syntax. * JSP:: Java code embedded in HTML. * RPM:: Shell scripts in RPM Spec Files. * Noweb:: Noweb literate programs. Writing Submode Classes * Basic Classes:: Writing a simple submode class. * Paired Delimiters:: Matching paired delimiters. * Region Placement:: Placing the region more accurately. * Submode Groups:: Grouping several classes together. * Calculated Submodes:: Deciding the submode at run-time. * Calculated Faces:: Deciding the display face at run-time. * Insertion Commands:: Inserting regions automatically. * Region Names:: Naming regions for syntax grouping. * Other Hooks:: Running code at arbitrary points. * Delimiters:: Controlling delimiter overlays. * Misc Keywords:: Other miscellaneous options. Indices * Concept Index:: Index of MMM Mode Concepts. * Function Index:: Index of functions and variables. * Keystroke Index:: Index of key bindings in MMM Mode. @end detailmenu @end menu @node Overview, Basics, Top, Top @comment node-name, next, previous, up @chapter Overview of MMM Mode @cindex overview of mmm-mode @cindex mmm-mode, overview of MMM Mode is a minor mode for Emacs which allows Multiple Major Modes to coexist in a single buffer. The name is an abbreviation of `Multiple Major Modes'@footnote{The name is derived from @file{mmm.el} for XEmacs by Gongquan Chen , from which MMM Mode was adapted.}. A major mode is a customization of Emacs for editing a certain type of text, such as code for a specific programming language. @xref{Major Modes, , , emacs, The Emacs Manual}, for details. MMM Mode is a general extension to Emacs which is useful whenever one file contains text in two or more programming languages, or that should be in two or more different modes. For example: @itemize @bullet @item CGI scripts written in any language, from Perl to PL/SQL, may want to output verbatim HTML, and the writer of such scripts may want to use Emacs' html-mode or sgml-mode to edit this HTML code, while remaining in the appropriate programming language mode for the rest of the file. @xref{Here-documents}, for example. @item There are now many ``content delivery systems'' which turn the CGI script idea around and simply add extra commands to an HTML file, often in some programming language, which are interpreted on the server. @xref{Mason}, @xref{Embperl}, @xref{ePerl}, @xref{JSP}. @item HTML itself can also contain embedded languages such as Javascript and CSS styles, for which Emacs has different major modes. @xref{Javascript}, and @xref{Embedded CSS}, for example. @item The idea of ``literate programming'' requires the same file to contain documentation (written as text, html, latex, etc.) and code (in an appropriate programming language). @xref{Noweb}, for example. @item Emacs allows files of any type to contain `local variables', which can include Emacs Lisp code to be evaluated. @xref{File Variables, , , emacs, The Emacs Manual}. It may be easier to edit this code in Emacs Lisp mode than in whatever mode is used for the rest of the file. @xref{File Variables}. @item There are many more possible uses for MMM Mode. RPM spec files can contain shell scripts (@pxref{RPM}). Email or newsgroup messages may contain sample code. And so on. We encourage you to experiment. @end itemize @menu * Basic Concepts:: A simple explanation of how it works. * Installation:: How to install MMM Mode. * Quick Start:: Getting started using MMM Mode quickly. @end menu @node Basic Concepts, Installation, Overview, Overview @comment node-name, next, previous, up @section Basic Concepts @cindex dominant major mode @cindex major mode, dominant @cindex default major mode @cindex major mode, default @cindex submode regions @cindex regions, submode @cindex overlays, submode @cindex submode overlays @cindex mmm-ification The way MMM Mode works is as follows. Each buffer has a @dfn{dominant} or @dfn{default} major mode, which is chosen as major modes normally are: the user can set it interactively, or it can be chosen automatically with `auto-mode-alist' (@pxref{Choosing Modes, , , emacs, The Emacs Manual}). Within the file, MMM Mode creates @dfn{submode regions} within which other major modes are in effect. While the point is in a submode region, the following changes occur: @enumerate @item The local keymap is that of the submode. This means the key bindings for the submode are available, while those of the dominant mode are not. @item The mode line (@pxref{Mode Line, , , emacs, The Emacs Manual}) changes to show which submode region is active. This can be configured; see @ref{Mode Line}. @item The major mode menu, both on the menu bar and the mouse popup, are that of the submode. @item Some local variables of the submode shadow those of the default mode (@pxref{Local Variables}). For the user, this serves to help make Emacs behave as if the submode were the major mode. @item The syntax table and indentation are those of the submode. @item Font-lock (@pxref{Font Lock, , , emacs, The Emacs Manual}) fontifies correctly for the submode. @item The submode regions are highlighted by a background color; see @ref{Region Coloring}. @end enumerate The submode regions are represented internally by Emacs Lisp objects known as @dfn{overlays}. Some of the above are implemented by overlay properties, and others are updated by an MMM Mode function in `post-command-hook'. You don't need to know this to use MMM Mode, but it may make any error messages you come across more understandable. @xref{Overlays, , , elisp, The GNU Emacs Lisp Reference Manual}, for more information on overlays. Because overlays are not saved with a file, every time a file is opened, they must be created. Creating submode regions is occasionally referred to as @dfn{mmm-ification}. (I've never had occasion to pronounce this, but if I did I would probably say `mummification'. Like what they did in ancient Egypt.) You can mmm-ify a buffer interactively, but most often MMM Mode will find and create submode regions automatically based on a buffer's file extension, dominant mode, or local variables. @node Installation, Quick Start, Basic Concepts, Overview @comment node-name, next, previous, up @section Installing MMM Mode MMM Mode has a standard installation process. See the file INSTALL for generic information on this process. To summarize, unpack the archive, @command{cd} to the created MMM Mode directory, type @samp{./configure}, then @samp{make}, then @samp{make install}. If all goes correctly, this will compile the MMM Mode elisp files, install them in your local site-lisp directory, and install the MMM Mode info file @file{mmm.info} in your local info directory. Now you need to configure your Emacs initialization file (usually @file{~/.emacs}) to use MMM Mode. First, Emacs has to know where to find MMM Mode. In other words, the MMM Mode directory has to be in @code{load-path}. This can be done in the parent directory's @file{subdirs.el} file, or in the init file with a line such as: @lisp (add-to-list 'load-path "/path/to/site-lisp/mmm/") @end lisp Once @code{load-path} is configured, MMM Mode must be loaded. You can load all of MMM Mode with the line @lisp (require 'mmm-mode) @end lisp @noindent but if you use MMM Mode only rarely, it may not be desirable to load all of it at the beginning of every editing session. You can load just enough of MMM Mode so it will turn itself on when necessary and load the rest of itself, by using instead the line @lisp (require 'mmm-auto) @end lisp @noindent in your initialization file. One more thing you may want to do right now is to set the variable @code{mmm-global-mode}. If this variable is @code{nil} (the default), MMM Mode will never turn itself on. If it is @code{t}, MMM Mode will turn itself on in every buffer. Probably the most useful value for it, however, is the symbol @code{maybe} (actually, anything that is not @code{nil} and not @code{t}), which causes MMM Mode to turn itself on in precisely those buffers where it would be useful. You can do this with a line such as: @lisp (setq mmm-global-mode 'maybe) @end lisp @noindent in your initialization file. @xref{Global Mode}, for more detailed information. @node Quick Start, , Installation, Overview @comment node-name, next, previous, up @section Getting Started Quickly Perhaps the simplest way to create submode regions is to do it interactively by specifying a region. First you must turn MMM Mode on---say, with @kbd{M-x mmm-mode}---then place point and mark around the area you want to make into a submode region, type @kbd{C-c % C-r}, and enter the desired major mode. @xref{Interactive}, for more details. A better way to add submode regions is by using submode classes, which store a lot of useful information for MMM Mode about how to add and manipulate the regions created. @xref{Submode Classes}, for more details. There are several sample submode classes that come with MMM Mode, which are documented later in this manual. Look through these and determine if one of them fits your needs. If so, I suggest reading the comments on that mode. Then come back here to find out to use it. To apply a submode class to a buffer interactively, turn MMM Mode on as above, then type @kbd{C-c % C-c} and enter the name of the class. Submode regions should be added automatically, if there are any regions in the buffer appropriate to the submode class. If you want a given file to always use a given submode class, you can express this in a file variable: add a line containing the string @samp{-*- mmm-classes: @var{class} -*-} at the top of the file. @xref{File Variables, , , emacs, The Emacs Manual}, for more information and other methods. Now whenever MMM Mode is turned on in that file, it will be mmm-ified according to @var{class}. If @code{mmm-global-mode} is non-nil, then MMM Mode will turn itself on whenever a file with a @code{mmm-classes} local variable is opened. @xref{Global Mode}, for more information. If you want a submode class to apply to @emph{all} files in a certain major mode or with a certain extension, add a line such as this to your initialization file: @lisp (mmm-add-mode-ext-class @var{mode} @var{extension} @var{class}) @end lisp @noindent After this call, any file opened whose name matches the regular expression @var{extension} @emph{and} whose default mode is @var{mode} will be automatically mmm-ified according to @var{class} (assuming @code{mmm-global-mode} is non-nil). If one of @var{extension} or @var{mode} is @code{nil}, a file need only satisfy the other one to be mmm-ified. You can now read the rest of this manual to learn more about how MMM Mode works and how to configure it to your preferences. If none of the supplied submode classes fit your needs, then you can try to write your own. @xref{Writing Classes}, for more information. @node Basics, Customizing, Overview, Top @comment node-name, next, previous, up @chapter MMM Mode Basics This chapter explains the most important parts of how to use MMM Mode. @menu * MMM Minor Mode:: The Emacs minor mode that manages it all. * Submode Classes:: What they are and how to use them. * Selecting Classes:: How MMM Mode knows what classes to use. * Insertion:: Inserting new submode regions automatically. * Re-parsing:: Re-scanning for submode regions. * Interactive:: Adding submode regions manually. * Global Mode:: Turning MMM Mode on automatically. @end menu @node MMM Minor Mode, Submode Classes, Basics, Basics @comment node-name, next, previous, up @section The MMM Minor Mode @cindex mode, mmm minor @cindex minor mode, mmm @cindex mmm minor mode An Emacs minor mode is an optional feature which can be turned on or off in a given buffer, independently of the major mode. @xref{Minor Modes, , , emacs, The Emacs Manual}. MMM Mode is implemented as a minor mode which manages the submode regions. This minor mode must be turned on in a buffer for submode regions to be effective. When activated, the MMM Minor mode is denoted by @samp{MMM} in the mode line (@pxref{Mode Line}). @menu * Enabling MMM Mode:: Turning MMM Mode on and off. * MMM Mode Keys:: Default key bindings in MMM Mode. @end menu @node Enabling MMM Mode, MMM Mode Keys, MMM Minor Mode, MMM Minor Mode @comment node-name, next, previous, up @subsection Enabling MMM Mode @cindex mmm mode, turning on @cindex mmm mode, turning off @cindex turning on mmm mode @cindex turning off mmm mode @cindex mmm mode, enabling @cindex mmm mode, disabling @cindex enabling mmm mode @cindex disabling mmm mode If @code{mmm-global-mode} is non-@code{nil} (@pxref{Global Mode}), then the MMM minor mode will be turned on automatically whenever a file with associated submode classes is opened (@pxref{Selecting Classes}). It is also turned on by interactive mmm-ification (@pxref{Interactive}), although the interactive commands do not have key bindings when it is not on and must be invoked via @kbd{M-x}. You can also turn it on (or off) manually with @kbd{M-x mmm-mode}, in which case it applies all submode classes associated with the buffer. Turning MMM Mode off automatically removes all submode regions from the buffer. @deffn Command mmm-mode @var{arg} Toggle the state of MMM Mode in the current buffer. If @var{arg} is supplied, turn MMM Mode on if and only if @var{arg} is positive. @end deffn @defun mmm-mode-on Turn MMM Mode on unconditionally in the current buffer. @end defun @defun mmm-mode-off Turn MMM Mode off unconditionally in the current buffer. @end defun @defvar mmm-mode This variable represents whether MMM Mode is on in the current buffer. Do not set this variable directly; use one of the above functions. @end defvar @node MMM Mode Keys, , Enabling MMM Mode, MMM Minor Mode @comment node-name, next, previous, up @subsection Key Bindings in MMM Mode @cindex mmm mode key bindings @cindex key bindings in mmm mode @findex mmm-insertion-help @kindex C-c % h When MMM Mode is on, it defines a number of key bindings. By default, these are bound after the prefix sequence @kbd{C-c %}. Minor mode keymaps are supposed to use @kbd{C-c @var{punctuation}} sequences, and I find this one to be a good mnemonic because @samp{%} is used by Mason to denote special tags. This prefix key can be customized; @ref{Key Bindings}. There are two types of key bindings in MMM Mode: @dfn{commands} and @dfn{insertions}. Command bindings run MMM Mode interactive functions to do things like re-parse the buffer or end the current submode region, and are defined statically as normal Emacs key-bindings. Insertion bindings insert submode region skeletons with delimiters into the buffer, and are defined dynamically, according to which submode classes (@pxref{Submode Classes}) are in effect, via a keymap default binding. To distinguish between the two, MMM Mode uses distinct modifier keys for each. By default, command bindings use the control key (e.g. @kbd{C-c % C-b} re-parses the buffer), and insertion bindings do not (e.g. @kbd{C-c % p}, when the Mason class is in effect, inserts a @samp{<%perl>...} region). This makes the command bindings different from in previous versions, however, so the variable @code{mmm-use-old-bindings} is provided. If this variable is set to `t' before MMM Mode is loaded, the bindings will be reversed: insertion bindings will use the control key and command bindings will not. Normally, Emacs gives help on a prefix command if you type @kbd{C-h} after that command (e.g. @kbd{C-x C-h} displays all key bindings starting with @kbd{C-x}). Because of how insertion bindings are implemented dynamically with a default binding, they do not show up when you hit @kbd{C-c % C-h}. For this reason, MMM Mode defines the command @kbd{C-c % h} which displays a list of all currently valid insertion key sequences. If you use the defaults for command and insertion bindings, the @kbd{C-h} and @kbd{h} should be mnemonic. In the rest of this manual, I will assume you are using the defaults for the mode prefix (@kbd{C-c %}) and the command and insertion modifiers. You can customize them, however; @ref{Key Bindings}. @node Submode Classes, Selecting Classes, MMM Minor Mode, Basics @comment node-name, next, previous, up @section Understanding Submode Classes @cindex submode classes @cindex classes, submode A submode class represents a ``type'' of submode region. It specifies how to find the regions, what their delimiters look like, what submode they should be, how to insert them, and how they behave in other ways. It is represented by a symbol, such as @code{mason} or @code{eval-elisp}. For example, in the Mason set of classes, there is one class representing all @samp{<%...%>} inline Perl regions, and one representing regions such as @samp{<%perl>...}, @samp{<%init>...}, and so on. These are different to Mason, but to Emacs they are all just Perl sections, so they are covered by the same submode class. But it would be tedious if whenever we wanted to use the Mason classes, we had to specify both of these. (Actually, this is a simplification: there are some half a dozen Mason submode classes.) So submode classes can also ``group'' others together, and we can refer to the @code{mason} class and mean all of them. The way a submode class is used is to @dfn{apply} it to a buffer. This scans the buffer for regions which should be submode regions according to that class, and also remembers the class for later, so that new submode regions can be inserted and scanned for later. @node Selecting Classes, Insertion, Submode Classes, Basics @comment node-name, next, previous, up @section How MMM Mode selects submode classes Submode classes that apply to a buffer come from three sources: mode/extension-associated classes, file-local classes, and interactive MMM-ification (@pxref{Interactive}). Whenever MMM Mode is turned on in a buffer (@pxref{MMM Minor Mode}, and @ref{Global Mode}), it inspects the value of two variables to determine which classes to automatically apply to the buffer. This covers the first two sources; the latter is covered in a later chapter. @menu * File Classes:: Classes for a single file. * Mode-Ext Classes:: Classes for a given mode or extension. * Global Classes:: Classes for all MMM Mode buffers. @end menu @node File Classes, Mode-Ext Classes, Selecting Classes, Selecting Classes @comment node-name, next, previous, up @subsection File-Local Submode Classes @defvar mmm-classes This variable is always buffer-local when set. Its value should be either a single symbol or a list of symbols. Each symbol represents a submode class that is applied to the buffer. @end defvar @code{mmm-classes} is usually set in a file local variables list. @xref{File Variables, , , emacs, The Emacs Manual}. The easiest way to do this is for the first line of the file to contain the string @samp{-*- mmm-classes: @var{classes} -*-}, where @var{classes} is the desired value of @code{mmm-classes} for the file in question. It can also be done with a local variables list at the end of the file. @node Mode-Ext Classes, Global Classes, File Classes, Selecting Classes @comment node-name, next, previous, up @subsection Submode Classes Associated with Modes and Extensions @defopt mmm-mode-ext-classes-alist This global variable associates certain submode classes with major modes and/or file extensions. Its value is a list of elements of the form @code{(@var{mode} @var{ext} @var{class})}. Any buffer whose major mode is @var{mode} (a symbol) @emph{and} whose file name matches @var{ext} (a regular expression) will automatically have the submode class @var{class} applied to it. If @var{mode} is @code{nil}, then only @var{ext} is considered to determine if a buffer fits the criteria, and vice versa. Thus if both @var{mode} and @var{ext} are nil, then @var{class} is applied to @emph{all} buffers in which MMM Mode is on. Note that @var{ext} can be any regular expression, although its name indicates that it most often refers to the file extension. If @var{class} is the symbol @code{t}, then no submode class is actually applied for this association. However, if @code{mmm-global-mode} is non-@code{nil} and non-@code{t}, MMM Mode will be turned on in matching buffers even if there are no actual submode classes being applied. @xref{Global Mode}. @end defopt @defun mmm-add-mode-ext-class @var{mode} @var{ext} @var{class} This function adds an element to @code{mmm-mode-ext-classes-alist}, associating the submode class @var{class} with the major mode @var{mode} and extension @var{ext}. Older versions of MMM Mode required this function to be used to control the value of @code{mmm-mode-ext-classes-alist}, rather than setting it directly. In this version it is provided purely for convenience and backward compatibility. @end defun @node Global Classes, , Mode-Ext Classes, Selecting Classes @comment node-name, next, previous, up @subsection Globally Applied Classes and the Universal Class In addition to file-local and mode-ext-associated submode classes, MMM Mode also allows you to specify that certain submode classes apply to @emph{all} buffers in which MMM Mode is enabled. @defopt mmm-global-classes This variable's value should be a list of submode classes that apply to all buffers with MMM Mode on. It can be overriden in a file local variables list, such as to disable global class for a specific file. Its default value is @code{(universal)}. @end defopt The default global class is the ``universal class'', which is defined in the file @file{mmm-univ.el} (loaded automatically), and allows the author of text to specify that a certain section of it be in a specific major mode. Thus, for example, when writing an email message that includes sample code, the author can allow readers of the message (who use emacs and MMM) to view the code in the appropriate major mode. The syntax used is @samp{@{%@var{mode}%@} ... @{%/@var{mode}%@}}, where @var{mode} should be the name of the major mode, with or without the customary @samp{-mode} suffix: for example, both @samp{cperl} and @samp{cperl-mode} are acceptable. The universal class also defines an insertion key, @samp{/}, which prompts for the submode to use. @xref{Insertion}. The universal class is most useful when @code{mmm-global-mode} is set to @code{t}; @ref{Global Mode}. @node Insertion, Re-parsing, Selecting Classes, Basics @comment node-name, next, previous, up @section Inserting new submode regions So much for noticing submode regions already present when you open a file. When editing a file with MMM Mode on, you will often want to add a new submode region. MMM Mode provides several facilities to help you. The simplest is to just hit a few keys and have the region and its delimiters inserted for you. Each submode class can define an association of keystrokes with ``skeletons'' to insert a submode region. If there are several submode classes enabled in a buffer, it is conceivable that the keys they use for insertion might conflict, but unlikely as most buffers will not use more than one or two submode classes groups. As an example of how insertion works, consider the Mason classes. In a buffer with MMM Mode enabled and Mason associated, the key sequence @kbd{C-c % p} inserts the following perl section (the semicolon is to prevent CPerl Mode from getting confused---@pxref{Mason}): @example <%perl>-<-; -!- ->- @end example In this schematic representation, the string @samp{-!-} represents the position of point (the cursor), @samp{-<-} represents the beginning of the submode region, and @samp{->-} its end. All insertion keys come after the MMM Mode prefix keys (by default @kbd{C-c %}; @pxref{Key Bindings}) and are by default single characters such as @kbd{p}, @kbd{%}, and @kbd{i}. To avoid confusion, all the MMM Mode commands are bound by default to control characters (after the same prefix keys), such as @kbd{C-b}, @kbd{C-%} and @kbd{C-r}. This is a change from earlier versions of MMM Mode, and can be customized; see @ref{Key Bindings}. To find out what insertion keys are available, consult the documentation for the submode class you are using. If it is one of the classes supplied with MMM Mode, you can find it in this Info file. Because insertion keys are implemented with a ``default binding'' for flexibility, they do not show up in the output of @kbd{C-h m} and cannot be found with @kbd{C-h k}. For this reason, MMM Mode supplies the command @kbd{C-c % h} (@code{mmm-insertion-help} to view the available insertion keys. @node Re-parsing, Interactive, Insertion, Basics @comment node-name, next, previous, up @section Re-Parsing Submode Regions @cindex re-parsing submode regions @cindex parsing submode regions @cindex submode regions, re-parsing @cindex regions, submode, re-parsing @cindex submode regions, clearing @cindex clearing submode regions @cindex regions, submode, clearing @kindex C-c % C-b @kindex C-c % C-g @kindex C-c % C-% @kindex C-c % C-5 @kindex C-c % C-k Describe @code{mmm-parse-buffer}, @code{mmm-parse-region}, @code{mmm-parse-block}, and @code{mmm-clear-current-region}. @node Interactive, Global Mode, Re-parsing, Basics @comment node-name, next, previous, up @section Interactive MMM-ification Functions @cindex interactive mmm-ification @cindex mmm-ification, interactive @cindex mmm-ification by region @cindex mmm-ification by regexp @cindex mmm-ification by class @cindex region, mmm-ification by @cindex regexp, mmm-ification by @cindex class, mmm-ification by @kindex C-c % C-r @kindex C-c % C-c @kindex C-c % C-x @cindex mmm-ification, interactive history @cindex history of interactive mmm-ification @cindex interactive mmm-ification, history of There are several commands you can use to create submode regions interactively, rather than by applying a submode class to a buffer. These commands (in particular, @code{mmm-ify-region}), can be useful when editing a file or email message containing a snippet of code in some other language. Also see @ref{Global Classes}, for an alternate approach to the same problem. @table @kbd @item C-c % C-r Creates a submode region between point and mark. Prompts for the submode to use, which must be a valid Emacs major mode name, such as @code{emacs-lisp-mode} or @code{cperl-mode}. Adds markers to the interactive history. (@code{mmm-ify-region}) @item C-c % C-c Applies an already-defined submode class to the buffer, which it prompts for. Adds this class to the interactive history. (@code{mmm-ify-by-class}) @item C-c % C-x Scans the buffer for submode regions (prompts for the submode) using front and back regular expressions that it also prompts for. Briefly, it starts at the beginning of the buffer and searches for the front regexp. If it finds a match, it searches for the back regexp. If it finds a match for that as well, it makes a submode region between the two matches and continues searching until no more matches are found. Adds the regexps to the interactive history. (@code{mmm-ify-by-regexp}) @end table These commands are also useful when designing a new submode class (@pxref{Submode Classes}). Working with the regexps interactively can make it easier to debug and tune the class before starting to use it on automatic. All these commands also add to value of the following variable. @defvar mmm-interactive-history Stores a history of all interactive mmm-ification that has been performed in the current buffer. This way, for example, the re-parsing functions (@pxref{Re-parsing}) will respect interactively added regions, and the insertion keys for classes that were added interactively are available. @end defvar If for any reason you want to ``wipe the slate clean'', this command should help you. By default, it has no key binding, so you must invoke it with @kbd{M-x mmm-clear-history @key{RET}}. @deffn Command mmm-clear-history Clears all history of interactive mmm-ification in the current buffer. This command does not affect existing submode regions; to remove them, you may want to re-parse the buffer with @kbd{C-c % C-b} (@code{mmm-parse-buffer}). @end deffn @node Global Mode, , Interactive, Basics @comment node-name, next, previous, up @section MMM Global Mode @cindex mode, mmm global @cindex global mmm mode @cindex mmm global mode @vindex mmm-never-modes When a file has associated submode classes (@pxref{Selecting Classes}), you may want MMM Mode to turn itself on and parse that file for submode regions automatically whenever it is opened in an Emacs buffer. The value of the following variable controls when MMM Mode turns itself on automatically. @defopt mmm-global-mode Do not be misled by the fact that this variable's name ends in @samp{-mode}: it is not a simple on/off switch. There are three possible (meanings of) values for it: @code{t}, @code{nil}, and anything else. When this variable is @code{nil}, MMM Mode is never enabled automatically. If it is enabled manually, such as by typing @kbd{M-x mmm-mode}, any submode classes associated with the buffer will still be used, however. When this variable is @code{t}, MMM Mode is enabled automatically in @emph{all} buffers, including those not visiting files, except those whose major mode is an element of @code{mmm-never-modes}. The default value of this variable contains modes such as @code{help-mode} and @code{dired-mode} in which most users would never want MMM Mode, and in which MMM might cause problems. When this variable is neither @code{nil} nor @code{t}, MMM Mode is enabled automatically in all buffers that would have associated submode classes; i.e. only if there would be something for it to do. The value of @code{mmm-never-modes} is still respected, however. Note that this can include buffers not visiting files, if that buffer's major mode is present in @code{mmm-mode-ext-classes-alist} with a @code{nil} value for @var{ext} (@pxref{Mode-Ext Classes}). Submode class values of @code{t} in @code{mmm-mode-ext-classes-alist} cause MMM Mode to be enabled in matching buffers, but supply no submode classes to be applied. @end defopt @menu * Major Mode Hook:: Using MMM's Major Mode Hook @end menu @node Major Mode Hook, , Global Mode, Global Mode @comment node-name, next, previous, up @subsection The Major Mode Hook @cindex hook, major mode @cindex major mode hook @vindex mmm-major-mode-hook This section is intended for users who understand Emacs Lisp and want to know how MMM Global Mode is implemented, and perhaps use the same technique. In fact, MMM Mode exports a hook variable that you can use easily, without understanding any of the details---see below. In order to enable itself in @emph{all} buffers, however, MMM Mode has to hook itself into all major modes. Global Font Lock Mode from the standard Emacs distribution (@pxref{Font Lock, , , emacs, The Emacs Manual}) has a similar problem, and solves it by adding a function to @code{change-major-mode-hook}, which is run by @code{kill-all-local-variables}, which is run in turn by all major mode functions at the @emph{beginning}. This function stores a list of which buffers need fontification. It then adds a different function to @code{post-command-hook}, which checks if the current buffer needs fontification, and if so performs it. MMM Global Mode uses the same technique. In the interests of generality, and for your use, the function that MMM Mode runs in @code{post-command-hook} (@code{mmm-run-major-mode-hook}) is not specific to MMM Mode, but rather runs the hook variable @code{mmm-major-mode-hook}, which by default contains a function (@code{mmm-mode-on-maybe}) which possibly turns MMM Mode on, depending on the value of @code{mmm-global-mode}. Thus, to run another function in all major modes, all you need to do is add it to this hook. For example, the following line in an initialization file will turn on Auto Fill Mode (@pxref{Auto Fill, , , emacs, The Emacs Manual}) in all buffers: @lisp (add-hook 'mmm-major-mode-hook 'turn-on-auto-fill) @end lisp @node Customizing, Supplied Classes, Basics, Top @comment node-name, next, previous, up @chapter Customizing MMM Mode This chapter explains how to customize the appearance and functioning of MMM Mode however you want. @menu * Region Coloring:: Changing or removing background colors. * Preferred Modes:: Choosing which major modes to use. * Mode Line:: What is displayed in the mode line. * Key Bindings:: Customizing the MMM Mode key bindings. * Local Variables:: What local variables are saved for submodes. * Changing Classes:: Changing the supplied submode classes. * Hooks:: How to make MMM Mode run your code. @end menu @node Region Coloring, Preferred Modes, Customizing, Customizing @comment node-name, next, previous, up @section Customizing Region Coloring @cindex faces, submode @cindex submode faces @cindex customizing submode faces @cindex default submode face By default, MMM Mode highlights all submode regions with a background color. There are three levels of this decoration, controlled by the following variable: @defopt mmm-submode-decoration-level This variable controls the level of coloring of submode regions. It should be one of the integers 0, 1, or 2, representing (respectively) none, low, and high coloring. @end defopt No coloring means exactly that. Submode regions have the same background as the rest of the text. This produces the minimal interference with font-lock coloration. In particular, if you want to use background colors for font-lock, this may be a good idea, because the submode highlight, if present, overrides any font-lock background coloring. Low coloring uses the same background color for all submode regions. This color is specified with the face @code{mmm-default-submode-face} (@pxref{Faces, , , emacs, The Emacs Manual}) which can be customized, either through the Emacs ``customize'' interface or using direct Lisp commands such as @code{set-face-background}. Of course, other aspects of the face can also be set, such as the foreground color, bold, underline, etc. These are more likely to conflict with font-lock, however, so only a background color is recommended. High coloring uses multiple background colors, depending on the function of the submode region. The recognized functions and their meanings are as follows: @table @samp @item init Code that is executed at the beginning of (something), as initialization of some sort. @item cleanup Code that is executed at the end of (something), as some sort of clean up facility. @item declaration Code that provides declarations of some sort, perhaps global or local arguments, variables, or methods. @item comment Text that is not executed as code, but instead serves to document the code around it. Submode regions of this function often use a mode such as Text Mode rather than a programming language mode. @item output An expression that is evaluated and its value interpolated into the output produced. @item code Executed code not falling under any other category. @item special Submode regions not falling under any other category, such as component calls. @end table The different background colors are provided by the faces @code{mmm-@var{function}-submode-face}, which can be customized in the same way as @code{mmm-default-submode-face}. @node Preferred Modes, Mode Line, Region Coloring, Customizing @comment node-name, next, previous, up @section Preferred Major Modes Certain of the supplied submode classes know only the language that certain sections are written in, but not what major mode you prefer to use to edit such code. For example, many people prefer CPerl mode over Perl mode; you may have a special mode for Javascript or just use C++ mode. This variable allows you to tell submodes such as Mason (@pxref{Mason}) and Embedded Javascript (@pxref{Javascript}) what major mode to use for the submodes: @defopt mmm-major-mode-preferences The elements of this list are cons cells of the form @code{(@var{language} . @var{mode})}. @var{language} should be a symbol such as @code{perl}, @code{html-js}, or @code{java}, while @var{mode} should be the name of a major mode such as @code{perl-mode}, @code{cperl-mode}, @code{javascript-mode}, or @code{c++-mode}. You probably won't have to set this variable at all; MMM tries to make intelligent guesses about what modes you prefer. For example, if a function called @code{javascript-mode} exists, it is chosen, otherwise @code{c++-mode} is used. Similarly for @code{jde-mode} and @code{java-mode}. @end defopt If you do need to change the defaults, you may find the following function convenient. @defun mmm-set-major-mode-preferences @var{language} @var{mode} &optional @var{default} Set the preferred major mode for LANGUAGE to MODE. If there is already a mode specified for LANGUAGE, and DEFAULT is nil or unsupplied, then it is changed. If DEFAULT is non-nil, then any existing mode is unchanged. This is used by packages to ensure that some mode is present, but not override any user-specified mode. If you are not writing a submode class, you should ignore the third argument. @end defun Thus, for example, to use @code{my-java-mode} for Java code, you would use the following line: @lisp (mmm-set-major-mode-preferences 'java 'my-java-mode) @end lisp @node Mode Line, Key Bindings, Preferred Modes, Customizing @comment node-name, next, previous, up @section Customizing the Mode Line Display By default, when in a submode region, MMM Mode changes the section of the mode line (@pxref{Mode Line, , , emacs, The Emacs Manual}) that normally displays the major mode name---for example, @samp{HTML}---to instead show both the dominant major mode and the currently active submode---for example, @samp{HTML[CPerl]}. You can change this format, however. @defopt mmm-submode-mode-line-format The value of this variable should be a string containing one or both of the escape sequences @samp{~M} and @samp{~m}. The string displayed in the major mode section of the mode line when in a submode is obtained by replacing all occurrences of @samp{~M} with the dominant major mode name and @samp{~m} with the currently active submode name. For example, to display only the currently active submode, set this variable to @samp{~m}. The default value is @samp{~M[~m]}. @end defopt The MMM minor mode also normally displays the string @samp{MMM} in the minor mode section of the mode line to indicate when it is active. You can customize or disable this as well. @defopt mmm-mode-string This string is displayed in the minor mode section of the mode line when the MMM minor mode is active. If nonempty, it should begin with a space to separate the MMM indicator from that of other minor modes. To eliminate the indicator entirely, set this variable to the empty string. @end defopt @node Key Bindings, Local Variables, Mode Line, Customizing @comment node-name, next, previous, up @section Customizing the MMM Mode Key Bindings The default MMM Mode key bindings are explained in @ref{MMM Mode Keys}, and in @ref{Insertion}. There are a couple of ways to customize these bindings. @defopt mmm-mode-prefix-key The value of this variable (default is @kbd{C-c %}) should be a key sequence to use as the prefix for the MMM Mode keymap. Minor modes typically use @kbd{C-c} followed by a punctuation character, but you can change it to any user-available key sequence. To have an effect, this variable should be set before MMM Mode is loaded. @end defopt @defopt mmm-use-old-command-keys When this variable is @code{nil}, MMM Mode commands use the control modifier and insertion keys no modifier. Any other value switches the two, so that @code{mmm-parse-buffer}, for example, is bound to @kbd{C-c % b}, while perl-section insertion in the Mason class is bound to @kbd{C-c % C-p}. This variable should be set before MMM Mode is loaded to have an effect. @end defopt When MMM is loaded, it uses the value of @code{mmm-use-old-command-keys} to set the values of the variables @code{mmm-command-modifiers} and @code{mmm-insert-modifiers}, so if you prefer you can set these variables instead. They should each be a list of key modifiers, such as @code{(control)} or @code{()}. The Meta modifier is used in some of the command and insertion keys, so it should not be used, and the Shift modifier is not particularly portable between Emacsen---if it works for you, feel free to use it. Other modifiers, such as Hyper and Super, are not universally available, but are valid when present. @node Local Variables, Changing Classes, Key Bindings, Customizing @comment node-name, next, previous, up @section Changing Saved Local Variables A lot of the functionality of MMM Mode---that which makes the major mode appear to change---is implemented by saving and restoring the values of local variables, or pseudo-variables. You can customize what variables are saved, and how, with the following variable. @defvar mmm-save-local-variables At its simplest, this is a list each of whose elements is a buffer-local variable whose value is saved and restored for each major mode. Each elements can also, however, be a list whose first element is the variable symbol and whose subsequent elements specify how and where the variable is to be saved. The second element of the list, if present, should be one of the symbols @code{global}, @code{buffer}, or @code{region}. If not present, the default value is @code{global}. The third element, if present, should be a list of major mode symbols in which to save the variable. In the list form, the variable symbol itself can be replaced with a cons cell of two functions, one to get the value and one to set the value. This is called a ``pseudo-variable''. @end defvar Globally saved variables are the same in all (MMM-controlled) buffers and submode regions of each major mode listed in the third argument, or all major modes if it is @code{t} or not present. Buffer-saved variables are the same in all submode regions of a given major mode in each buffer, and region-saved variables can be different for each submode region. Pseudo-variables are used, for example, to save and restore the syntax table (@pxref{Syntax, , , emacs, The Emacs Manual}) and mode keymaps (@pxref{Keymaps, , , emacs, The Emacs Manual}). @node Changing Classes, Hooks, Local Variables, Customizing @comment node-name, next, previous, up @section Changing the Supplied Submode Classes If you need to use MMM with a syntax for which a submode class is not supplied, and you have some facility with Emacs Lisp, you can write your own; see @ref{Writing Classes}. However, sometimes you will only want to make a slight change to one of the supplied submode classes. You can do this, after that class is loaded, with the following functions. @defun mmm-set-class-parameter @var{class} @var{param} @var{value} Set the value of the keyword parameter @var{param} of the submode class @var{class} to @var{value}. @xref{Writing Classes}, for an explanation of the meaning of each keyword parameter. This creates a new parameter if one is not already present in the class. @end defun @defun mmm-get-class-parameter @var{class} @var{param} Get the value of the keyword parameter @var{param} for the submode class @var{class}. Returns @code{nil} if there is no such parameter. @end defun @node Hooks, , Changing Classes, Customizing @comment node-name, next, previous, up @section Hooks Provided by MMM Mode MMM Mode defines several hook variables (@pxref{Hooks, , , emacs, The Emacs Manual}) which are run at different times. The most often used is @code{mmm-major-mode-hook} which is described in @ref{Major Mode Hook}, but there are a couple others. @defvar mmm-mode-hook This normal hook is run whenever MMM Mode is enabled in a buffer. @end defvar @defvar mmm-@var{major-mode}-hook This is actually a whole set of hook variables, a different one for every major mode. Whenever MMM Mode is enabled in a buffer, the corresponding hook variable for the dominant major mode is run. @end defvar @defvar mmm-@var{submode}-submode-hook Again, this is a set of one hook variable per major mode. These hooks are run whenever a submode region of the corresponding major mode is created in any buffer, with point at the start of the new submode region. @end defvar @defvar mmm-@var{class}-class-hook This is a set of one hook variable per submode class. These hooks are run when a submode class is first applied to a given buffer. @end defvar Submode classes also have a @code{:creation-hook} parameter which should be a function to run whenever a submode region is created with that class, with point at the beginning of the submode region. This can be set for supplied submode classes with @code{mmm-set-class-parameter}; @ref{Changing Classes}. @node Supplied Classes, Writing Classes, Customizing, Top @comment node-name, next, previous, up @chapter Supplied Submode Classes This chapter describes the submode classes that are supplied with MMM Mode. @menu * Mason:: Mason server-side Perl in HTML. * File Variables:: Elisp code in File Variables. * Here-documents:: Code in shell and Perl here-documents. * Javascript:: Javascript embedded in HTML. * Embedded CSS:: CSS Styles embedded in HTML. * Embperl:: Another syntax for Perl in HTML. * ePerl:: A general Perl-embedding syntax. * JSP:: Java code embedded in HTML. * RPM:: Shell scripts in RPM Spec Files. * Noweb:: Noweb literate programs. @end menu @node Mason, File Variables, Supplied Classes, Supplied Classes @comment node-name, next, previous, up @section Mason: Perl in HTML Mason is a syntax to embed Perl code in HTML and other documents. See @uref{http://www.masonhq.com} for more information. The submode class for Mason components is called `mason' and is loaded on demand from `mmm-mason.el'. The current Mason class is intended to correctly recognize all syntax valid in Mason @value{MASON_VERSION}. There are insertion keys for most of the available syntax; use @code{mmm-insertion-help} (@kbd{C-c % h} by default) with Mason on to get a list. If you want to have mason submodes automatically in all Mason files, you can use automatic mode and filename associations; the details depend on what you call your Mason components and what major mode you use. @xref{Mode-Ext Classes}. If you use an extension for your Mason files that emacs does not automatically place in your preferred HTML Mode, you will probably want to associate that extension with your HTML Mode as well; @ref{Choosing Modes, , , emacs, The Emacs Manual}. This also goes for ``special'' Mason files such as autohandlers and dhandlers. The Perl mode used is controlled by the user: @xref{Preferred Modes}. The default is to use CPerl mode, if present. Unfortunately, there are also certain problems with CPerl mode in submode regions. (Not to say that the original perl-mode would do any better---it hasn't been much tried.) First of all, the first line of a Perl section is usually indented as if it were a continuation line. A fix for this is to start with a semicolon on the first line. The insertion key commands do this whenever the Mason syntax allows it. @example <%perl>; print $var; @end example In addition, some users have reported that the CPerl indentation sometimes does not work. This problem has not yet been tracked down, however, and more data about when it happens would be helpful. Some people have reported problems using PSGML with Mason. Adding the following line to a @file{.emacs} file should suffice to turn PSGML off and cause emacs to use a simpler HTML mode: @lisp (autoload 'html-mode "sgml-mode" "HTML Mode" t) @end lisp Earlier versions of PSGML may require instead the following fix: @lisp (delete '("\\.html$" . sgml-html-mode) auto-mode-alist) (delete '("\\.shtml$" . sgml-html-mode) auto-mode-alist) @end lisp Other users report using PSGML with Mason and MMM Mode without difficulty. If you don't have problems and want to use PSGML, you may need to replace @code{html-mode} in the suggested code with @code{sgml-html-mode}. (Depending on your version of PSGML, this may not be necessary.) Similarly, if you are using XEmacs and want to use the alternate HTML mode @code{hm--html-mode}, replace @code{html-mode} with that symbol. One problem that crops up when using PSGML with Mason is that even ignoring the special tags and Perl code (which, as I've said, haven't caused me any problems), Mason components often are not a complete SGML document. For instance, my autohandlers often say @example <% $m->call_next %> @end example in which case the actual components contain no doctype declaration, @code{}, @code{}, or @code{}, confusing PSGML. One solution I've found is to use the variable @code{sgml-parent-document} in such incomplete components; try, for example, these lines at the end of a component. @example %# Local Variables: %# sgml-parent-document: ("autohandler" "body" nil ("body")) %# sgml-doctype: "/top/level/autohandler" %# End: @end example This tells PSGML that the current file is a sub-document of the file @file{autohandler} and is included inside a @code{} tag, thus alleviating its confusion. @node File Variables, Here-documents, Mason, Supplied Classes @comment node-name, next, previous, up @section Elisp in a Local Variables List Emacs allows the author of a file to specify major and minor modes to be used while editing that file, as well as specifying values for other local Elisp variables, with a File Variables list. @xref{File Variables, , , emacs, The Emacs Manual}. Since file variables values are Elisp objects (and with the @code{eval} special ``variable'', they are forms to be evaluated), one might want to edit them in @code{emacs-lisp-mode}. The submode class @code{file-variables} allows this, and is suitable for turning on in a given file with @code{mmm-classes}, or in all files with @code{mmm-global-classes}. @node Here-documents, Javascript, File Variables, Supplied Classes @comment node-name, next, previous, up @section Here-documents One of the long-time standard syntaxes for outputting large amounts of code (or text, or HTML, or whatever) from a script (notably shell scripts and Perl scripts) is the here-document syntax: @example print < Test Page END_HTML @end example The @code{here-doc} submode class recognizes this syntax, and can even guess the correct submode to use in many cases. For instance, it would put the above example in @code{html-mode}, noticing the string @samp{HTML} in the name of the here-document. If you use less than evocative here-document names, or if the submode is recognized incorrectly for any other reason, you can tell it explicitly what submode to use. @defopt mmm-here-doc-mode-alist The value of this variable should be an alist, each element a cons pair associating a regular expression to a submode symbol. Whenever a here-document name matches one of these regexps, the corresponding submode is applied. For example, if this variable contains the element @code{("CODE" . cc-mode)}, then any here-document whose name contains the string @samp{CODE} will be put in @code{cc-mode}. The value of this variable overrides any guessing that the @code{here-doc} submode class would do otherwise. @end defopt @node Javascript, Embedded CSS, Here-documents, Supplied Classes @comment node-name, next, previous, up @section Javascript in HTML The submode class @code{html-js} allows for embedding Javascript code in HTML documents. It recognizes both this syntax: @example @end example and this syntax: @example @end example The mode used for Javascript regions is controlled by the user; @xref{Preferred Modes}. @node Embedded CSS, Embperl, Javascript, Supplied Classes @comment node-name, next, previous, up @section CSS embedded in HTML CSS (Cascading Style Sheets) can also be embedded in HTML. The @code{embedded-css} submode class recognizes this syntax: @example @end example It uses @code{css-mode} if present, @code{c++-mode} otherwise. This can be customized: @xref{Preferred Modes}. @node Embperl, ePerl, Embedded CSS, Supplied Classes @comment node-name, next, previous, up @section Embperl: More Perl in HTML Embperl is another syntax for embedding Perl in HTML. See @uref{http://perl.apache.org/embperl} for more information. The @code{embperl} submode class recognizes most if not all of the Embperl embedding syntax. Its Perl mode is also controllable by the user; @xref{Preferred Modes}. @node ePerl, JSP, Embperl, Supplied Classes @comment node-name, next, previous, up @section ePerl: General Perl Embedding Yet another syntax for embedding Perl is called ePerl. See @uref{http://www.engelschall.com/sw/eperl/} for more information. The @code{eperl} submode class handles this syntax, using the Perl mode specified by the user; @xref{Preferred Modes}. @node JSP, RPM, ePerl, Supplied Classes @comment node-name, next, previous, up @section JSP: Java Embedded in HTML JSP (Java Server Pages) is a syntax for embedding Java code in HTML. The submode class @code{jsp} handles this syntax, using a Java mode specified by the user; @xref{Preferred Modes}. The default is @code{jde-mode} if present, otherwise @code{java-mode}. @node RPM, Noweb, JSP, Supplied Classes @comment node-name, next, previous, up @section RPM Spec Files @file{mmm-rpm.el} contains the definition of an MMM Mode submode class for editing shell script sections within RPM (Redhat Package Manager) spec files. It is recommended for use in combination with @file{rpm-spec-mode.el} by Stig Bjørlykke and Steve Sanbeg (@uref{http://www.xemacs.org/~stigb/rpm-spec-mode.el}). Suggested setup code: @lisp (add-to-list 'mmm-mode-ext-classes-alist '(rpm-spec-mode "\\.spec\\'" rpm-sh)) @end lisp Thanks to Marcus Harnisch for contributing this submode class. @node Noweb, , RPM, Supplied Classes @comment node-name, next, previous, up @section Noweb literate programming @file{mmm-noweb.el} contains the definition of an MMM Mode submode class for editing Noweb documents. Most Noweb documents use \LaTeX for the documentation chunks. Code chunks in Noweb are document-specific, and the mode may be set with a local variable setting in the document. The variable @var{mmm-noweb-code-mode} controls the global code chunk mode. Since Noweb files may have many languages in their code chunks, this mode also allows setting the mode by specifying a mode in the first line or two of a code chunk, using the normal Emacs first-line mode setting syntax. Note that this first-line mode setting only matches a single word for the mode name, and does not support the variable name setting of the generalized first file line syntax. @verbatim % -*- mode: latex; mmm-noweb-code-mode: c++; -*- % First chunk delimiter! @ \noweboptions{smallcode} \title{Sample Noweb File} \author{Joe Kelsey\\ \nwanchorto{mailto:bozo@bozo.bozo}{\tt bozo@bozo.bozo}} \maketitle @ \section{Introduction} Normal noweb documentation for the required [[*]] chunk. <<*>>= // C++ mode here! // We might list the program here, or simply included chunks. <> @ %def myfile.cc @ \section{[[myfile.cc]]} This is [[myfile.cc]]. MMM noweb-mode understands code quotes in documentation. <>= // This section is indented separately from previous. @ @ \section{A Perl Chunk} We need a Perl chunk. <>= #!/usr/bin/perl # -*- perl -*- # Each differently named chunk is flowed separately. @ \section{Finish [[myfile.cc]]} When we resume a previously defined chunk, they are indented together. <>= // Pick up where we left off... @ @end verbatim The quoted code chunks inside documentation chunks are given the mode found in the variable @var{mmm-noweb-quote-mode}, if set, or the value in @var{mmm-noweb-code-mode} otherwise. Also, each quoted chunk is set to have a unique name to prevent them from being indented as a unit. Suggested setup code: @lisp (mmm-add-mode-ext-class 'latex-mode "\\.nw\\'" 'noweb) (add-to-list 'auto-mode-alist '("\\.nw\\'" . latex-mode)) @end lisp In mmm-noweb buffers, each differently-named code chunk has a different @code{:name}, allowing all chunks with the same name to get indented together. This mode also supplies special paragraph filling operations for use in documentation areas of the buffer. From a primary-mode (@code{latex-mode, , emacs}) region, pressing @kbd{C-c % C-q} will mark all submode regions with word syntax (@code{mmm-word-other-regions}), fill the current paragraph (@code{(fill-paragraph justify)}), and remove the syntax markings (@code{mmm-undo-syntax-other-regions}). Thanks to Joe Kelsey for contributing this class. @node Writing Classes, Indices, Supplied Classes, Top @comment node-name, next, previous, up @chapter Writing Submode Classes Sometimes (perhaps often) you may want to use MMM with a syntax for which it is suited, but for which no submode is supplied. In such cases you may have to write your own submode class. This chapter briefly describes how to write a submode class, from the basic to the advanced, with examples. @menu * Basic Classes:: Writing a simple submode class. * Paired Delimiters:: Matching paired delimiters. * Region Placement:: Placing the region more accurately. * Submode Groups:: Grouping several classes together. * Calculated Submodes:: Deciding the submode at run-time. * Calculated Faces:: Deciding the display face at run-time. * Insertion Commands:: Inserting regions automatically. * Region Names:: Naming regions for syntax grouping. * Other Hooks:: Running code at arbitrary points. * Delimiters:: Controlling delimiter overlays. * Misc Keywords:: Other miscellaneous options. @end menu @node Basic Classes, Paired Delimiters, Writing Classes, Writing Classes @comment node-name, next, previous, up @section Writing Basic Submode Classes @cindex simple submode classes @cindex submode classes, simple Writing a submode class can become rather complex, if the syntax to match is complicated and you want to take advantage of some of MMM Mode's extra features. But a simple submode class is not particularly difficult to write. This section describes the basics of writing submode classes. Submode classes are stored in the variable @code{mmm-classes-alist}. Each element of this list represents a single submode class. For convenience, the function @code{mmm-add-classes} takes a list of submode classes and adds them all to this alist. Each class is represented by a list containing the class name---a symbol such as @code{mason} or @code{html-js}---followed by pairs of keywords and arguments called a @dfn{class specifier}. For example, consider the specifier for the submode class @code{embedded-css}: @lisp (mmm-add-classes '((embedded-css :submode css :face mmm-declaration-submode-face :front "]*>" :back ""))) @end lisp The name of the submode is @code{embedded-css}, the first element of the list. The rest of the list consists of pairs of keywords (symbols beginning with a colon) such as @code{:submode} and @code{:front}, and arguments, such as @code{css} and @code{"]*>"}. It is the keywords and arguments that specify how the submode works. The order of keywords is not important; all that matters is the arguments that follow them. The three most important keywords are @code{:submode}, @code{:front}, and @code{:back}. The argument following @code{:submode} names the major mode to use in submode regions. It can be either a symbol naming a major mode, such as @code{text-mode} or @code{c++-mode}, or a symbol to look up in @code{mmm-major-mode-preferences} (@pxref{Preferred Modes}) such as @code{css}, as in this case. The arguments following @code{:front} and @code{:back} are regular expressions (@pxref{Regexps, , , emacs, The Emacs Manual}) that should match the delimiter strings which begin and end the submode regions. In our example, CSS regions begin with a @samp{} tag. The argument following @code{:face} specifies the face (background color) to use when @code{mmm-submode-decoration-level} is 2 (high coloring). @xref{Region Coloring}, for a list of canonical available faces. There are many more possible keywords arguments. In the following sections, we will examine each of them and their uses in writing submode classes. @node Paired Delimiters, Region Placement, Basic Classes, Writing Classes @comment node-name, next, previous, up @section Matching Paired Delimiters A simple pair of regular expressions does not always suffice to exactly specify the beginning and end of submode regions correctly. For this reason, there are several other possible keyword/argument pairs which influence the matching process. Many submode regions are marked by paired delimiters. For example, the tags used by Mason (@pxref{Mason}) include @samp{<%init>...} and @samp{<%args>...}. It would be possible to write a separate submode class for each type of region, but there is an easier way: the keyword argument @code{:save-matches}. If supplied and non-nil, it causes the regular expression @code{:back}, before being searched for, to be formatted by replacing all strings of the form @samp{~@var{N}} (where @var{N} is an integer) with the corresponding numbered subexpression of the match for @code{:front}. As an example, here is an excerpt from the @code{here-doc} submode class. @xref{Here-documents}, for more information about this submode. @lisp :front "<<\\([a-zA-Z0-9_-]+\\)" :back "^~1$" :save-matches 1 @end lisp The regular expression for @code{:front} matches @samp{<<} followed by a string of one or more alphanumeric characters, underscores, and dashes. The latter string, which happens to be the name of the here-document, is saved as the first subexpression, since it is surrounded by @samp{\(...\)}. Then, because the value of @code{:save-matches} is present and non-nil, the string @samp{~1} is replaced in the value of @code{:back} by the name of the here-document, thus creating a regular expression to match the correct ending delimiter. @node Region Placement, Submode Groups, Paired Delimiters, Writing Classes @comment node-name, next, previous, up @section Placing Submode Regions Precisely Normally, a submode region begins immediately after the end of the string matching the @code{:front} regular expression and ends immediately before the beginning of the string matching the @code{:back} regular expression. This can be changed with the keywords @code{:include-front} and @code{:include-back}. If their arguments are @code{nil}, or they do not appear, the default behavior is unchanged. But if the argument of @code{:include-front} (respectively, @code{:include-back}) is non-nil, the submode region will begin (respectively, end) immediately before (respectively, after) the string matching the @code{:front} (respectively, @code{:back}) regular expression. In other words, these keywords specify whether or not the delimiter strings are @emph{included} in the submode region. When @code{:front} and @code{:back} are regexps, the delimiter is normally considered to be the entire matched region. This can be changed using the @code{:front-match} and @code{:back-match} keywords. The values of the keywords is a number specifying the submatch. This defaults to zero (specifying the whole regexp). Two more keywords which affect the placement of the region @code{:front-offset} and @code{:back-offset}, which both take integers as arguments. The argument of @code{:front-offset} (respectively, @code{:back-offset}) gives the distance in characters from the beginning (respectively, ending) location specified so far, to the actual point where the submode region begins (respectively, ends). For example, if @code{:include-front} is nil or unsupplied and @code{:front-offset} is 2, the submode region will begin two characters after the end of the match for @code{:front}, and if @code{:include-back} is non-nil and @code{:back-offset} is -1, the region will end one character before the end of the match for @code{:back}. In addition to integers, the arguments of @code{:front-offset} and @code{:back-offset} can be functions which are invoked to move the point from the position specified by the matches and inclusions to the correct beginning or end of the submode region, or lists whose elements are either functions or numbers and whose effects are applied in sequence. To help disentangle these options, here is another excerpt from the @code{here-doc} submode class: @lisp :front "<<\\([a-zA-Z0-9_-]+\\)" :front-offset (end-of-line 1) :back "^~1$" :save-matches 1 @end lisp Here the value of @code{:front-offset} is the list @code{(end-of-line 1)}, meaning that from the end of the match for @code{:front}, go to the end of the line, and then one more character forward (thus to the beginning of the next line), and begin the submode region there. This coincides with the normal behavior of here-documents: they begin on the following line and go until the ending flag. If the @code{:back} should not be able to start a new submode region, set the @code{:end-not-begin} keyword to non-nil. @node Submode Groups, Calculated Submodes, Region Placement, Writing Classes @comment node-name, next, previous, up @section Defining Groups of Submodes Sometimes more than one submode class is required to accurately reflect the behavior of a single type of syntax. For example, Mason has three very different types of Perl regions: blocks bounded by matched tags such as @samp{<%perl>...}, inline output expressions bounded by @samp{<%...%>}, and single lines of code which simply begin with a @samp{%} character. In cases like these, it is possible to specify an ``umbrella'' class, to turn all these classes on or off together. @defun mmm-add-group @var{group} @var{classes} The submode classes @var{classes}, which should be a list of lists, similar to what might be passed to @code{mmm-add-classes}, are added just as by that function. Furthermore, another class named @var{group} is added, which encompasses all the classes in @var{classes}. @end defun Technically, an group class is specified with a @code{:classes} keyword argument, and the subsidiary classes are given a non-nil @code{:private} keyword argument to make them invisible. But in general, all you should ever need to know is how to invoke the function above. @defun mmm-add-to-group @var{group} @var{classes} Adds a list of classes to an already existing group. This can be used, for instance, to add a new quoting definition to @var{html-js} using this example to add the quote characters ``%=%'': @lisp (mmm-add-to-group 'html-js '((js-html :submode javascript :face mmm-code-submode-face :front "%=%" :back "%=%" :end-not-begin t))) @end lisp @end defun @node Calculated Submodes, Calculated Faces, Submode Groups, Writing Classes @comment node-name, next, previous, up @section Calculating the Correct Submode In most cases, the author of a submode class will know in advance what major mode to use, such as @code{text-mode} or @code{c++-mode}. If there are multiple possible modes that the user might desire, then @code{mmm-major-mode-preferences} should be used (@pxref{Preferred Modes}). The function @code{mmm-set-major-mode-preferences} can be used, with a third argument, to ensure than the mode is present. In some cases, however, the author has no way of knowing in advance even what language the submode region will be in. The @code{here-doc} class is one of these. In such cases, instead of the @code{:submode} keyword, the @code{:match-submode} keyword must be used. Its argument should be a function, probably written by the author of the submode class, which calculates what major mode each region should use. It is invoked immediately after a match is found for @code{:front}, and is passed one argument: a string representing the front delimiter. Normally this string is simply whatever was matched by @code{:front}, but this can be changed with the keyword @code{:front-form} (@pxref{Delimiters}). The function should then return a symbol that would be a valid argument to @code{:submode}: either the name of a mode, or that of a language to look up a preferred mode. If it detects an invalid match---for example, the user has specified a mode which is not available---it should @code{(signal 'mmm-no-matching-submode nil)}. Since here-documents can contain code in any language, the @code{here-doc} submode class uses @code{:match-submode} rather than @code{:submode}. The function it uses is @code{mmm-here-doc-get-mode}, defined in @file{mmm-sample.el}, which inspects the name of the here-document for flags indicating the proper mode. For example, this code should probably be in @code{perl-mode} (or @code{cperl-mode}): @example print <} and @code{