1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374
|
<!--startcut ==========================================================-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<title>EMACSulation LG #39</title>
<link rev="made" href="mailto:emarsden+emacs@laas.fr">
<meta name="keywords" content="emacs, template, expansions, dmacro">
<meta name="description" content="Templating mechanisms in Emacs: how
to use auto-inserted contents and skeletons."
<meta name="author" content="Eric Marsden">
<meta name="generator" content="Emacs">
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
ALINK="#FF0000">
<!--endcut ============================================================-->
<H4>
"Linux Gazette...<I>making Linux just a little more fun!</I>"
</H4>
<P> <HR> <P>
<!--===================================================================-->
<center>
<H1><font color="maroon">EMACSulation</font></H1>
<H4>By <a href="mailto:emarsden@mail.dotcom.fr">Eric Marsden</a></H4>
</center>
<P> <HR> <P>
<blockquote><small>
This column is devoted to making the best use of Emacs, text editor
extraordinaire. Each issue I plan to present an Emacs extension
which can improve your productivity, make the sun shine more brightly
and the grass greener.
</small></blockquote>
<h1>Templating</h1>
<p> Documents often conform to a boilerplate: a regular structure which is
boring to type in for each document. Most wordprocessors recognise this
and allow you to create templates for business letters, technical
reports, memos etc. Emacs can do one better than these static
"skeletons", since its templating mechanism allows you to
insert dynamically generated text, according to the file's name, your
login, the date, or the results of a shell command.
<p> The Emacs auto-insertion mechanism allows you to set up boilerplates
which will be instanciated upon file creation, based on the new file's
name or mode. For example, when you create a file called
<tt>lsys.h</tt>, it will ask you <em>Perform C / C++ header
auto-insertion?</em>, and if you say yes might insert something like
</p>
<table border="0" bgcolor="#E0E0E0" width="100%">
<tr><td>
<pre class="programlisting">
<font color="#ff0000">
/**********************************************************************
* lsys.h
*
* Eric Marsden <emarsden@mail.dotcom.fr>
* Time-stamp: <>
**********************************************************************/</font>
#<font color="#5f9ea0">ifndef</font> <font color="#b8860b">_LSYS_H_</font>
#<font color="#5f9ea0">define</font> <font color="#b8860b">_LSYS_H_</font>
#<font color="#5f9ea0">endif</font> <font color="#ff0000">/* _LSYS_H_ */</font>
</pre>
</td></tr></table>
<p> Note that <tt>#ifdefs</tt> have been generated to protect against
multiple inclusions of the header. You might want to add additional
elements such as your company's copyright blabber, skeletal revision
history comments, or an RCS version $Id. The auto-inserted content
depends on the major mode: upon creation of a file called
<tt>lsys.sgml</tt> the auto-inserted text might be </p>
<table border="0" bgColor="#E0E0E0" width="100%">
<tr><td>
<pre class="programlisting">
<<font color="#4682b4">!DOCTYPE</font> ARTICLE PUBLIC <font color="#a0522d">"-//Davenport//DTD DocBook V3.0//EN"</font> [
]>
<<font color="#0000cd">article</font>>
<<font color="#0000cd">artheader</font>>
<<font color="#0000cd">date</font>>1999-03-01<<font color="#0000cd">/date</font>>
<<font color="#0000cd">title</font>> <<font color="#0000cd">/title</font>>
<<font color="#0000cd">subtitle</font>> <<font color="#0000cd">/subtitle</font>>
<<font color="#0000cd">author</font>>
<<font color="#0000cd">firstname</font>>Eric<<font color="#0000cd">/firstname</font>>
<<font color="#0000cd">surname</font>>Marsden<<font color="#0000cd">/surname</font>>
<<font color="#0000cd">affiliation</font>><<font color="#0000cd">orgname</font>>CULTe<<font color="#0000cd">/orgname</font>><<font color="#0000cd">/affiliation</font>>
<<font color="#0000cd">/author</font>>
<<font color="#0000cd">authorinitials</font>>ecm<<font color="#0000cd">/authorinitials</font>>
<<font color="#0000cd">abstract</font>>
<<font color="#0000cd">para</font>>
<<font color="#0000cd">/para</font>>
<<font color="#0000cd">/abstract</font>>
<<font color="#0000cd">/artheader</font>>
<<font color="#0000cd">sect1</font>><<font color="#0000cd">title</font>> <<font color="#0000cd">/title</font>>
<<font color="#0000cd">para</font>>
<<font color="#0000cd">/para</font>>
<<font color="#0000cd">/sect1</font>>
<<font color="#0000cd">/article</font>>
</pre>
</td></tr></table>
<p> [These font-enhanced program listings were generated by Hrvoje Niksic's
excellent <a
href="http://jagor.srce.hr/~hniksic/htmlize.el">htmlize</a> package,
which generates HTML renderings of font-locked buffers.] Auto-insertion
can be activated by saying </p>
<table border="0" bgColor="#E0E0E0" width="100%">
<tr><td>
<pre>
(add-hook 'find-file-hooks 'auto-insert)
(setq auto-insert-directory (expand-file-name <font color="#a0522d">"~/.autoinsert/"</font>))
</pre>
</td></tr></table>
<p> The <strong>autoinsert package</strong> (written by Charlie Martin) is
distributed with default templates for several modes. There are two
ways of customizing the auto-inserted contents: the simplest (which
doesn't require any knowledge of elisp) involves placing files in
the directory <tt>~/.autoinsert/</tt> and registering them with
autoinsert: </p>
<table border="0" bgColor="#E0E0E0" width="100%">
<tr><td>
<pre>
(define-auto-insert "\\.html\\'" "autoinsert.html")
</pre>
</td></tr></table>
<p> The <tt>"\\.html\\'"</tt> is a regular expression which
matches filenames ending in <tt>.html</tt> (note the use of
<tt>\\'</tt> to match the end of a string, rather than <tt>$</tt> for
the end of a line, since filenames are allowed to contain newline
characters). This should lead to the contents of the file
<tt>~/.autoinsert/autoinsert.html</tt> being inserted automatically
when you create a file whose name ends in <tt>.html</tt>. This method
only allows insertion of static content. Insertion of dynamically
generated content is also possible if you know some Emacs Lisp; here is
some code which creates skeleton C or C++ headers, as in the first
example in this article: </p>
<table border="0" bgColor="#E0E0E0" width="100%">
<tr><td>
<pre class="programlisting">
<font color="#ff0000">;; autoinsert.el</font>
(define-auto-insert
(cons <font color="#a0522d">"\\.\\([Hh]\\)\\'"</font> <font color="#a0522d">"My C / C++ header"</font>)
'(nil
<font color="#a0522d">"/*"</font> (make-string 69 ?*) <font color="#a0522d">"\n"</font>
<font color="#a0522d">" * "</font> (file-name-nondirectory buffer-file-name) <font color="#a0522d">"\n"</font>
<font color="#a0522d">" *\n"</font>
<font color="#a0522d">" * "</font> (user-full-name) <font color="#a0522d">" <"</font> user-mail-address <font color="#a0522d">">\n"</font>
<font color="#a0522d">" * Time-stamp: <>\n"</font>
<font color="#a0522d">" *"</font> (make-string 69 ?*) <font color="#a0522d">"*/\n"</font>
(<font color="#4682b4">let*</font> ((noext (substring buffer-file-name 0 (match-beginning 0)))
(nopath (file-name-nondirectory noext))
(ident (concat <font color="#a0522d">"_"</font> (upcase nopath) <font color="#a0522d">"_H_"</font>)))
(concat <font color="#a0522d">"#ifndef "</font> ident <font color="#a0522d">"\n"</font>
<font color="#a0522d">"#define "</font> ident <font color="#a0522d">"\n\n\n"</font>
<font color="#a0522d">"\n\n#endif /* "</font> ident <font color="#a0522d">" */\n"</font>))))
</pre>
</td></tr></table>
<p> How does the autoinsertion work? Each time you open a file in Emacs, it
runs a special hook called <tt>find-file-hooks</tt>. This is where
things such as enabling syntactic highlighting or checking whether a
file is under a version control system (RCS or CVS) occur. The
<tt>add-hook</tt> line above latches the autoinsertion onto this hook.
<h2>Dmacro</h2>
<p> The <strong>Dynamic Macro</strong> package by Wayne Mesard allows you
to insert structured text at any time, not only at document creation
time. dmacro provides facilities such as prompting the user for input,
inserting the contents of a file or the output from a shell command,
and positioning the cursor or the mark after the insertion. One
particularly nice feature is the ability to indent autoinserted
contents according to the current mode. It could be used as a way of
enforcing (well, encouraging developers to adhere to) coding standards,
and can reduce development time by preventing typos in repetitive text.
dmacro is not distributed with Emacs; you will have to <a
href="ftp://ftp.sgi.com/other/dmacro/dmacro.tar.gz">download</a> and
install it (which is just a matter of saying <emph>make</emph>). It can
be activated by saying in your <tt>~/.emacs</tt> (where the
<tt>.dm</tt> file contains your personal macros; see below for some
examples): </p>
<table border="0" bgColor="#E0E0E0" width="100%">
<tr><td>
<pre class="programlisting">
(require 'dmacro) <font color="#ff0000">; dynamic macros</font>
(dmacro-load <font color="#a0522d">"~/elisp/ecm.dm"</font>)
</pre>
</td></tr></table>
<p> The dmacro package is very well documented, so I will only provide a
few motivating examples. Here is one which will insert the skeleton of
a <tt>for</tt> block in C-mode (macros can either be global, or
specific to a certain major mode): </p>
<table border="0" bgColor="#E0E0E0" width="100%">
<tr><td>
<pre class="programlisting">
# file ~/elisp/ecm.dm
# ================================== Stuff for C-derived modes =======
# MODE: c-mode c++-mode java-mode
ifor indent interactive for statement (prompts for variable name)
for (~(prompt var "Variable: ") = 0; ~prompt < ~@; ~prompt++)
{
~mark
}
#
</pre>
</td></tr></table>
<p> You activate the macro by typing <tt>C-c d ifor</tt> (with tab
completion on the macro's name). It should prompt you for the name of
the variable:
<p> <img src="./gx/marsden/dmacro1.gif">
<p> and the result should look like <a href="./gx/marsden/dmacro2.gif">this</a>. The
next example demonstrates how to insert a timestamp of the form
<tt>-ecm1999-02-29</tt> in the current buffer (pet peeve: given the
value of a uniform, standardized external representation for dates, I
make a point of systematically using the <a
href="http://www.cl.cam.ac.uk/~mgk25/iso-time.html">ISO 8601</a>
format). You invoke this macro by typing <tt>C-c d dstamp</tt>. The
corresponding code (which also demonstrates the use of an alias to
factorize out commonly used definitions) is: </p>
<table border="0" bgColor="#E0E0E0" width="100%">
<tr><td>
<pre class="programlisting">
# ALIAS: iso-date (eval (format-time-string "%Y-%m-%d"))
# ================================= Stuff for all modes ============
# MODE: nil
dstamp expand user id and date
-~user-id~(iso-date)
#
</pre>
</td></tr></table>
<h2>Related packages</h2>
<p> There are several other packages which provide similar functionality to
dmacro. <tt>tempo.el</tt> (included with both GNU Emacs and XEmacs) was
originally written as an adjunct to html-helper-mode, providing
facilities for inserting balanced bits of HTML markup, but can be used
for other purposes. It is also possible to extend the standard abbrev
mechanism to insert dynamically generated text by hacking the
abbrev-mode-hook, as explained in the <a
href="http://www.dejanews.com/getdoc.xp?AN=340841733">following
message</a> posted anonymously to <a
href="news:gnu.emacs.help">gnu.emacs.help</a>. Finally, there is <a
href="http://www.fmi.uni-passau.de/~wedler/template/">template.el</a>
by <a href="mailto:wedler!@!fmi.uni-passau.de">Christoph Wedler</a>
which seems very comprehensive.
<h2>Feedback</h2>
<p> The January 1999 EMACSulation on abbreviation mechanisms had a
bootstrap problem: I indicated how to create abbreviations and how to
have them read in automatically when Emacs starts up, but the
instructions that I gave weren't sufficient to get Emacs to save
abbrevs automatically when quitting. Thanks to Nat Makarevitch and Dave
Bennet for pointing this out. Here is a revised version of the code
that I proposed (the last line is what was missing): </p>
<table border="0" bgColor="#E0E0E0" width="100%">
<tr><td>
<pre class="programlisting">
<font color="red">
;; if there is an abbrev file, read it in</font>
(if (file-exists-p abbrev-file-name)
(read-abbrev-file))
(setq-default save-abbrevs t)
</pre>
</td></tr></table>
<p> A few European readers also asked about abbreviations containing 8bit,
non-ASCII characters. In its default state Emacs won't take them into
account, since it assumes that characters with the 8th bit set are non
word-constituent. To modify this (to take into account accented
characters in the iso-8859-1 character map, for example) you need to do
something like </p>
<table border="0" bgColor="#E0E0E0" width="100%">
<tr><td>
<pre class="programlisting">
(set-language-environment 'Latin-1) <font color="red">; GNU Emacs 20.x</font>
(require 'iso-syntax) <font color="red">; GNU Emacs 19.x</font>
</pre>
</td></tr></table>
<p> (there are major differences between the way that GNU Emacs 19.x and
20.x handle different character encodings; recent versions can handle
multibyte characters, required for representing asian languages. Rather
than using <a href="http://www.unicode.org/">Unicode</a>, Emacs uses
adjustable width characters. For XEmacs this <a
href="http://www.etl.go.jp/~mule/MulePage.html">MULE</a> (MULtilingual
enhancements for Emacs) support is a compile-time option in recent
versions.)
<h2>Next time ...</h2>
<p> Next month we'll look at spell checking with Emacs. Thanks to <a
href="mailto:arnu!@!laas.fr">Jean-Christophe Arnu</a> for commenting on
a draft of this article. Don't hesitate to contact me with comments,
corrections or suggestions (what's <em>your</em> favorite
couldn't-do-without Emacs extension package?). <code>C-u 1000 M-x
hail-emacs</code> !
<p> <strong>PS</strong>: Emacs isn't in any way limited to Linux, since
implementations exist for many other operating systems (and some
systems which only halfway operate). However, as one of the leading
bits of free software, one of the most powerful, complex and
customizable, I feel it has its place in the <i>Linux Gazette</i>.
<!--===================================================================-->
<P> <HR> <P>
<A HREF="../issue25/marsden.html">EMACSulation #1: Handling Compressed Files, February 1998</A><BR>
<A HREF="../issue26/marsden.html">EMACSulation #2: Internet Ready, March 1998</A><BR>
<A HREF="../issue27/marsden.html">EMACSulation #3: Ediff, April 1998</A><BR>
<A HREF="../issue29/marsden.html">EMACSulation #4: Emacs as a Server, June 1998</A><BR>
<A HREF="../issue31/marsden.html">EMACSulation #5: Customizing Emacs, August 1998</A><BR>
<A HREF="../issue36/marsden.html">EMACSulation #6: Saving Time, January 1999</A>
<!--===================================================================-->
<P> <hr> <P>
<center><H5>Copyright © 1999, Eric Marsden <BR>
Published in Issue 39 of <i>Linux Gazette</i>, April 1999</H5></center>
<!--===================================================================-->
<P> <hr> <P>
<A HREF="./lg_toc39.html"><IMG ALIGN=BOTTOM SRC="../gx/indexnew.gif"
ALT="[ TABLE OF CONTENTS ]"></A>
<A HREF="../lg_frontpage.html"><IMG ALIGN=BOTTOM SRC="../gx/homenew.gif"
ALT="[ FRONT PAGE ]"></A>
<A HREF="./sevenich.html"><IMG SRC="../gx/back2.gif"
ALT=" Back "></A>
<A HREF="./pollman.html"><IMG SRC="../gx/fwd.gif" ALT=" Next "></A>
<P> <hr> <P>
<!--startcut ==========================================================-->
</BODY>
</HTML>
<!--endcut ============================================================-->
|