This is mmm.info, produced by makeinfo version 4.2 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.4.8 of the MMM Mode Manual, last updated 9 March
2003. It documents version 0.4.8 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: Mason, Next: File Variables, Prev: Supplied Classes, Up: Supplied Classes
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;
%perl>
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
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
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
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
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
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
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
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
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
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
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
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 "")))
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 `"' 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
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>...%init>' and
`<%args>...%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
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
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>...%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
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 `