]> git.rkrishnan.org Git - .emacs.d.git/blob - emacs/nxhtml/related/smarty-mode.el
ad003b5c62455d92a5bb83890469a555a1069406
[.emacs.d.git] / emacs / nxhtml / related / smarty-mode.el
1 ;;; smarty-mode.el --- major mode for editing Smarty templates
2
3 ;; Author:       Vincent DEBOUT <deboutv@free.fr>
4 ;; Maintainer:  Vincent DEBOUT <deboutv@free.fr>
5 ;; Keywords:    languages smarty templates
6 ;; WWW:         http://deboutv.free.fr/lisp/smarty/
7
8 ;;; License
9
10 ;; This program is free software; you can redistribute it and/or
11 ;; modify it under the terms of the GNU General Public License
12 ;; as published by the Free Software Foundation; either version 2
13 ;; of the License, or (at your option) any later version.
14
15 ;; This program is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with this program; if not, write to the Free Software
22 ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23
24 ;; Minor changes by Lennart Borgman
25
26 (defconst smarty-version "0.0.5"
27   "Smarty Mode version number.")
28
29 (defconst smarty-time-stamp "2007-11-01"
30   "Smarty Mode time stamp for last update.")
31
32 (defconst smarty-is-xemacs (string-match "XEmacs" emacs-version)
33   "Non-nil if XEmacs is used.")
34
35 (require 'font-lock)
36 (when (not smarty-is-xemacs)
37   (require 'cc-mode)
38   (require 'custom)
39   (require 'etags))
40 (eval-when-compile
41   (require 'regexp-opt))
42 ;;(when smarty-is-xemacs
43   (require 'easymenu)
44   (require 'hippie-exp)
45 ;;)
46
47 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
48 ;;; Customization
49 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
50
51 ;;;###autoload
52 (defgroup smarty nil
53   "Customizations for Smarty mode."
54   :prefix "smarty-"
55   :group 'languages)
56
57 (defgroup smarty-mode nil
58   "Customizations for Smarty mode."
59   :group 'smarty)
60
61 (defcustom smarty-electric-mode t
62   "*Non-nil enables electrification (automatic template generation).
63 If nil, template generators can still be invoked through key bindings and
64 menu.  Is indicated in the modeline by \"/e\" after the mode name and can be
65 toggled by `\\[smarty-electric-mode]'."
66   :type 'boolean
67   :group 'smarty-mode)
68
69 (defcustom smarty-stutter-mode t
70   "*Non-nil enables stuttering.
71 Is indicated in the modeline by \"/s\" after the mode name and can be toggled
72 by `\\[smarty-stutter-mode]'."
73   :type 'boolean
74   :group 'smarty-mode)
75
76 (defgroup smarty-menu nil
77   "Customizations for menues."
78   :group 'smarty)
79
80 (defcustom smarty-source-file-menu t
81   "*Non-nil means add a menu of all source files in current directory."
82   :type 'boolean
83   :group 'smarty-menu)
84
85 (defgroup smarty-highlight nil
86   "Customizations for highlight."
87   :group 'smarty)
88
89 (defcustom smarty-highlight-plugin-functions t
90   "*Non-nil means highlight the plugin functions in the buffer."
91   :type 'boolean
92   :group 'smarty-highlight)
93
94 (defgroup smarty-template nil
95   "Customizations for templates."
96   :group 'smarty)
97
98 (defgroup smarty-header nil
99   "Customizations for header template."
100   :group 'smarty-template)
101
102 (defcustom smarty-file-header ""
103   "*String or file to insert as file header.
104 If the string specifies an existing file name, the contents of the file is
105 inserted, otherwise the string itself is inserted as file header.
106 Type `C-j' for newlines.
107 If the header contains RCS keywords, they may be written as <RCS>Keyword<RCS>
108 if the header needs to be version controlled.
109
110 The following keywords for template generation are supported:
111   <filename>    : replaced by the name of the buffer
112   <author>      : replaced by the user name and email address
113                   \(`user-full-name',`mail-host-address', `user-mail-address')
114   <login>       : replaced by user login name (`user-login-name')
115   <company>     : replaced by contents of option `smarty-company-name'
116   <date>        : replaced by the current date
117   <year>        : replaced by the current year
118   <copyright>   : replaced by copyright string (`smarty-copyright-string')
119   <cursor>      : final cursor position."
120   :type 'string
121   :group 'smarty-header)
122
123 (defcustom smarty-file-footer ""
124   "*String or file to insert as file footer.
125 If the string specifies an existing file name, the contents of the file is
126 inserted, otherwise the string itself is inserted as file footer (i.e. at
127 the end of the file).
128 Type `C-j' for newlines.
129 The same keywords as in option `smarty-file-header' can be used."
130   :type 'string
131   :group 'smarty-header)
132
133 (defcustom smarty-company-name ""
134   "*Name of company to insert in file header.
135 See option `smarty-file-header'."
136   :type 'string
137   :group 'smarty-header)
138
139 (defcustom smarty-copyright-string ""
140   "*Copyright string to insert in file header.
141 Can be multi-line string (type `C-j' for newline) and contain other file
142 header keywords (see option `smarty-file-header')."
143   :type 'string
144   :group 'smarty-header)
145
146 (defcustom smarty-date-format "%Y-%m-%d"
147   "*Specifies the date format to use in the header.
148 This string is passed as argument to the command `format-time-string'.
149 For more information on format strings, see the documentation for the
150 `format-time-string' command (C-h f `format-time-string')."
151   :type 'string
152   :group 'smarty-header)
153
154 (defcustom smarty-modify-date-prefix-string ""
155   "*Prefix string of modification date in Smarty file header.
156 If actualization of the modification date is called (menu,
157 `\\[smarty-template-modify]'), this string is searched and the rest
158 of the line replaced by the current date."
159   :type 'string
160   :group 'smarty-header)
161
162 (defcustom smarty-modify-date-on-saving nil
163   "*Non-nil means update the modification date when the buffer is saved.
164 Calls function `\\[smarty-template-modify]').
165
166 NOTE: Activate the new setting in a Smarty buffer by using the menu entry
167       \"Activate Options\"."
168   :type 'boolean
169   :group 'smarty-header)
170
171 (defgroup smarty-misc nil
172   "Miscellaneous customizations."
173   :group 'smarty)
174
175 (defcustom smarty-left-delimiter "{"
176   "Left escaping delimiter."
177   :type 'string
178   :group 'smarty-misc)
179
180 (defcustom smarty-right-delimiter "}"
181   "Right escaping delimiter."
182   :type 'string
183   :group 'smarty-misc)
184
185 (defcustom smarty-intelligent-tab t
186   "*Non-nil means `TAB' does indentation, word completion and tab insertion.
187 That is, if preceding character is part of a word then complete word,
188 else if not at beginning of line then insert tab,
189 else if last command was a `TAB' or `RET' then dedent one step,
190 else indent current line (i.e. `TAB' is bound to `smarty-electric-tab').
191 If nil, TAB always indents current line (i.e. `TAB' is bound to
192 `indent-according-to-mode').
193
194 NOTE: Activate the new setting in a Smarty buffer by using the menu entry
195       \"Activate Options\"."
196   :type 'boolean
197   :group 'smarty-misc)
198
199 (defcustom smarty-word-completion-in-minibuffer t
200   "*Non-nil enables word completion in minibuffer (for template prompts).
201
202 NOTE: Activate the new setting by restarting Emacs."
203   :type 'boolean
204   :group 'smarty-misc)
205
206 (defcustom smarty-word-completion-case-sensitive nil
207   "*Non-nil means word completion using `TAB' is case sensitive.
208 That is, `TAB' completes words that start with the same letters and case.
209 Otherwise, case is ignored."
210   :type 'boolean
211   :group 'smarty-misc)
212
213 ;; Functions
214
215 (defun smarty-customize ()
216   "Call the customize function with `smarty' as argument."
217   (interactive)
218   (customize-browse 'smarty))
219
220 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
221 ;; Variables
222 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
223
224 (defvar smarty-menu-max-size 20
225   "*Specifies the maximum size of a menu before splitting it into submenues.")
226
227 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
228 ;; Menu tools functions
229 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
230
231 (defun smarty-menu-split (list title)
232   "Split menu LIST into several submenues, if number of
233 elements > `smarty-menu-max-size'."
234   (if (> (length list) smarty-menu-max-size)
235       (let ((remain list)
236             (result '())
237             (sublist '())
238             (menuno 1)
239             (i 0))
240         (while remain
241           (setq sublist (cons (car remain) sublist))
242           (setq remain (cdr remain))
243           (setq i (+ i 1))
244           (if (= i smarty-menu-max-size)
245               (progn
246                 (setq result (cons (cons (format "%s %s" title menuno)
247                                          (nreverse sublist)) result))
248                 (setq i 0)
249                 (setq menuno (+ menuno 1))
250                 (setq sublist '()))))
251         (and sublist
252              (setq result (cons (cons (format "%s %s" title menuno)
253                                       (nreverse sublist)) result)))
254         (nreverse result))
255     list))
256
257 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
258 ;; Source file menu
259 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
260
261 (defvar smarty-sources-menu nil)
262
263 ;; Create the source menu
264 (defun smarty-add-source-files-menu ()
265   "Scan directory for all Smarty source files and generate menu.
266 The directory of the current source file is scanned."
267   (interactive)
268   (message "Scanning directory for source files ...")
269   (let ((newmap (current-local-map))
270         (file-list (smarty-get-source-files))
271         menu-list found)
272     ;; Create list for menu
273     (setq found nil)
274     (while file-list
275       (setq found t)
276       (setq menu-list (cons (vector (car file-list)
277                                    (list 'find-file (car file-list)) t)
278                            menu-list))
279       (setq file-list (cdr file-list)))
280     (setq menu-list (smarty-menu-split menu-list "Sources"))
281     (when found (setq menu-list (cons "--" menu-list)))
282     (setq menu-list (cons ["*Rescan*" smarty-add-source-files-menu t] menu-list))
283     (setq menu-list (cons "Sources" menu-list))
284     ;; Create menu
285     (easy-menu-add menu-list)
286     (easy-menu-define smarty-sources-menu newmap
287                       "Smarty source files menu" menu-list))
288   (message ""))
289
290 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
291 ;; Smarty menu
292 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
293
294 (defun smarty-create-mode-menu ()
295   "Create Smarty Mode menu."
296   `("Smarty"
297     ("Templates"
298      ("Built-in Functions"
299       ["capture" smarty-template-capture t]
300       ["config_load" smarty-template-config-load t]
301       ["else" smarty-template-else t]
302       ["elseif" smarty-template-elseif t]
303       ["foreach" smarty-template-foreach t]
304       ["foreachelse" smarty-template-foreachelse t]
305       ["if" smarty-template-if t]
306       ["include" smarty-template-include t]
307       ["include_php" smarty-template-include-php t]
308       ["insert" smarty-template-insert t]
309       ["ldelim" smarty-template-ldelim t]
310       ["literal" smarty-template-literal t]
311       ["php" smarty-template-php t]
312       ["rdelim" smarty-template-rdelim t]
313       ["section" smarty-template-section t]
314       ["sectionelse" smarty-template-sectionelse t]
315       ["strip" smarty-template-strip t])
316      ("Custom Functions"
317       ["assign" smarty-template-assign t]
318       ["counter" smarty-template-counter t]
319       ["cycle" smarty-template-cycle t]
320       ["debug" smarty-template-debug t]
321       ["eval" smarty-template-eval t]
322       ["fetch"  smarty-template-fetch t]
323       ["html_checkboxes" smarty-template-html-checkboxes t]
324       ["html_image" smarty-template-html-image t]
325       ["html_options" smarty-template-html-options t]
326       ["html_radios" smarty-template-html-radios t]
327       ["html_select_date" smarty-template-html-select-date t]
328       ["html_select_time" smarty-template-html-select-time t]
329       ["html_table" smarty-template-html-table t]
330       ["mailto" smarty-template-mailto t]
331       ["math" smarty-template-math t]
332       ["popup" smarty-template-popup t]
333       ["popup_init" smarty-template-popup-init t]
334       ["textformat" smarty-template-textformat t])
335      ("Variable Modifiers"
336       ["capitalize" smarty-template-capitalize t]
337       ["cat" smarty-template-cat t]
338       ["count_characters" smarty-template-count-characters t]
339       ["count_paragraphs" smarty-template-count-paragraphs t]
340       ["count_sentences" smarty-template-count-sentences t]
341       ["count_words" smarty-template-count-words t]
342       ["date_format" smarty-template-date-format t]
343       ["default" smarty-template-default t]
344       ["escape" smarty-template-escape t]
345       ["indent" smarty-template-indent t]
346       ["lower" smarty-template-lower t]
347       ["nl2br" smarty-template-nl2br t]
348       ["regex_replace" smarty-template-regex-replace t]
349       ["replace" smarty-template-replace t]
350       ["spacify" smarty-template-spacify t]
351       ["string_format" smarty-template-string-format t]
352       ["strip" smarty-template-vstrip t]
353       ["strip_tags" smarty-template-strip-tags t]
354       ["truncate" smarty-template-truncate t]
355       ["upper" smarty-template-upper t]
356       ["wordwrap" smarty-template-wordwrap t])
357      ("Plugins (Functions)"
358       ("BlockRepeatPlugin"
359        ["repeat" smarty-template-repeat t]
360        ["str_repeat" smarty-template-str-repeat t])
361       ("ClipCache"
362        ["clipcache" smarty-template-clipcache t]
363        ["include_clipcache" smarty-template-include-clipcache t])
364       ("SmartyFormtool"
365        ["formtool_checkall" smarty-template-formtool-checkall t]
366        ["formtool_copy" smarty-template-formtool-copy t]
367        ["formtool_count_chars" smarty-template-formtool-count-chars t]
368        ["formtool_init" smarty-template-formtool-init t]
369        ["formtool_move" smarty-template-formtool-move t]
370        ["formtool_moveall" smarty-template-formtool-moveall t]
371        ["formtool_movedown" smarty-template-formtool-movedown t]
372        ["formtool_moveup" smarty-template-formtool-moveup t]
373        ["formtool_remove" smarty-template-formtool-remove t]
374        ["formtool_rename" smarty-template-formtool-rename t]
375        ["formtool_save" smarty-template-formtool-save t]
376        ["formtool_selectall" smarty-template-formtool-selectall t])
377       ("SmartyPaginate"
378        ["paginate_first" smarty-template-paginate-first t]
379        ["paginate_last" smarty-template-paginate-last t]
380        ["paginate_middle" smarty-template-paginate-middle t]
381        ["paginate_next" smarty-template-paginate-next t]
382        ["paginate_prev" smarty-template-paginate-prev t])
383       ("SmartyValidate"
384        ["validate" smarty-template-validate t]))
385      ("Plugins (Variable Modifiers)"
386       ("AlternativeDateModifierPlugin"
387        ["date_format2" smarty-template-date-formatto t])
388       ("B2Smilies"
389        ["B2Smilies" smarty-template-btosmilies t])
390       ("BBCodePlugin"
391        ["bbcode2html" smarty-template-bbcodetohtml t])
392       )
393      "--"
394      ["Insert Header" smarty-template-header t]
395      ["Insert Footer" smarty-template-footer t]
396      ["Insert Date" smarty-template-insert-date t]
397      ["Modify Date" smarty-template-modify t])
398     "--"
399     ["Show Messages" smarty-show-messages :keys "C-c M-m"]
400     ["Smarty Mode Documentation" smarty-doc-mode :keys "C-c C-h"]
401     ["Version" smarty-version :keys "C-c C-v"]
402     "--"
403     ("Options"
404      ("Mode"
405       ["Electric Mode"
406        (progn (customize-set-variable 'smarty-electric-mode
407                                       (not smarty-electric-mode))
408               (smarty-mode-line-update))
409        :style toggle :selected smarty-electric-mode :keys "C-c C-m C-e"]
410       ["Stutter Mode"
411        (progn (customize-set-variable 'smarty-stutter-mode
412                                       (not smarty-stutter-mode))
413               (smarty-mode-line-update))
414        :style toggle :selected smarty-stutter-mode :keys "C-c C-m C-s"]
415       "--"
416       ["Customize Group..." (customize-group 'smarty-mode) t])
417      ("Menu"
418       ["Source Menu"
419        (customize-set-variable 'smarty-source-file-menu
420                                (not smarty-source-file-menu))
421        :style toggle :selected smarty-source-file-menu]
422       "--"
423       ["Customize Group..." (customize-group 'smarty-menu) t])
424      ("Highlight"
425       ["Highlight plugin functions"
426        (progn (customize-set-variable 'smarty-highlight-plugin-functions
427                                       (not smarty-highlight-plugin-functions)))
428        :style toggle :selected smarty-highlight-plugin-functions]
429       "--"
430       ["Customize Group..." (customize-group 'smarty-highlight) t])
431      ("Template"
432       ("Header"
433        ["Header template..."
434         (customize-option 'smarty-file-header) t]
435        ["Footer template..."
436         (customize-option 'smarty-file-footer) t]
437        ["Company..."
438         (customize-option 'smarty-company-name) t]
439        ["Copyright..."
440         (customize-option 'smarty-copyright-string) t]
441        ["Date format..."
442         (customize-option 'smarty-date-format) t]
443        ["Modify date prefix..."
444         (customize-option 'smarty-modify-date-prefix-string) t]
445        ["Modify date on saving"
446         (customize-set-variable 'smarty-modify-date-on-saving
447                                 (not smarty-modify-date-on-saving))
448         :style toggle :selected smarty-modify-date-on-saving]
449        "--"
450        ["Customize Group..." (customize-group 'smarty-header) t])
451       "--"
452       ["Customize Group..." (customize-group 'smarty-template) t])
453      ("Miscellaneous"
454       ["Left delimiter..."
455        (customize-option 'smarty-left-delimiter) t]
456       ["Right delimiter..."
457        (customize-option 'smarty-right-delimiter) t]
458       ["Use Intelligent Tab"
459        (progn (customize-set-variable 'smarty-intelligent-tab
460                                       (not smarty-intelligent-tab))
461               (smarty-activate-customizations))
462        :style toggle :selected smarty-intelligent-tab]
463       ["Word Completion in Minibuffer"
464        (progn (customize-set-variable 'smarty-word-completion-in-minibuffer
465                                       (not smarty-word-completion-in-minibuffer))
466               (message "Activate new setting by saving options and restarting Emacs"))
467        :style toggle :selected smarty-word-completion-in-minibuffer]
468       ["Completion is case sensitive"
469        (customize-set-variable 'smarty-word-completion-case-sensitive
470                                (not smarty-word-completion-case-sensitive))
471        :style toggle :selected smarty-word-completion-case-sensitive]
472       "--"
473       ["Customize Group..." (customize-group 'smarty-misc) t])
474      "--"
475      ["Save Options" customize-save-customized t]
476      ["Activate Options" smarty-activate-customizations t]
477      ["Browse Options..." smarty-customize t])))
478
479 (defvar smarty-mode-menu-list (smarty-create-mode-menu)
480   "Smarty Mode menu.")
481
482 (defvar smarty-mode-map nil
483   "Keymap for Smarty Mode.")
484
485 (defun smarty-update-mode-menu ()
486   "Update Smarty Mode menu."
487   (interactive)
488   (easy-menu-remove smarty-mode-menu-list)
489   (setq smarty-mode-menu-list (smarty-create-mode-menu))
490   (easy-menu-add smarty-mode-menu-list)
491   (easy-menu-define smarty-mode-menu smarty-mode-map
492                     "Menu keymap for Smarty Mode." smarty-mode-menu-list))
493
494
495
496
497 (defvar smarty-mode-hook nil)
498
499 (defvar smarty-functions nil
500   "List of Smarty functions.")
501
502 (defvar smarty-functions-regexp nil
503   "Regexp for Smarty functions.")
504
505 (defconst smarty-01-functions
506   '("capture" "config_load" "foreach" "foreachelse" "include"
507     "include_php" "insert" "if" "elseif" "else" "ldelim" "rdelim"
508     "literal" "php" "section" "sectionelse" "strip" "assign" "counter"
509     "cycle" "debug" "eval" "fetch" "html_checkboxes" "html_image"
510     "html_options" "html_radios" "html_select_date" "html_select_time"
511     "html_table" "math" "mailto" "popup_init" "popup" "textformat")
512   "Smarty built-in & custom functions.")
513
514 (defvar smarty-modifiers nil
515   "List of Smarty variable modifiers.")
516
517 (defvar smarty-modifiers-regexp nil
518   "Regexp for Smarty variable modifiers.")
519
520 (defconst smarty-01-modifiers
521   '("capitalize" "cat" "count_characters" "count_paragraphs"
522     "count_sentences" "count_words" "date_format" "default"
523     "escape" "indent" "lower" "nl2br" "regex_replace" "replace"
524     "spacify" "string_format" "strip" "strip_tags" "truncate"
525     "upper" "wordwrap")
526   "Smarty variable modifiers.")
527
528 (defvar smarty-plugins-functions nil
529   "List of Smarty functions.")
530
531 (defvar smarty-plugins-functions-regexp nil
532   "Regexp for Smarty functions.")
533
534 (defconst smarty-01-plugins-functions
535   '("validate" "formtool_checkall" "formtool_copy" "formtool_count_chars"
536     "formtool_init" "formtool_move" "formtool_moveall"
537     "formtool_movedown" "formtool_moveup" "formtool_remove"
538     "formtool_rename" "formtool_save" "formtool_selectall"
539     "paginate_first" "paginate_last" "paginate_middle"
540     "paginate_next" "paginate_prev" "clipcache" "include_clipcache"
541     "repeat" "str_repeat")
542   "Smarty plugins functions.")
543
544 (defvar smarty-plugins-modifiers nil
545   "List of Smarty variable modifiers.")
546
547 (defvar smarty-plugins-modifiers-regexp nil
548   "Regexp for Smarty functions.")
549
550 (defconst smarty-01-plugins-modifiers
551   '("B2Smilies" "bbcode2html" "date_format2")
552   "Smarty plugins modifiers.")
553
554 (defconst smarty-constants
555   (eval-when-compile
556         (regexp-opt
557          '("TRUE" "FALSE" "NULL") t))
558   "Smarty constants.")
559
560
561 ;; Syntax table creation
562 (defvar smarty-mode-syntax-table nil
563   "Syntax table for smarty-mode.")
564
565 (defvar smarty-mode-ext-syntax-table nil
566   "Syntax table extended by `_' used in `smarty-mode' buffers.")
567
568 (defun smarty-create-syntax-table ()
569   (if smarty-mode-syntax-table
570       ()
571     (setq smarty-mode-syntax-table (make-syntax-table))
572
573     ;; Make | a punctuation character
574     (modify-syntax-entry ?| "." smarty-mode-syntax-table)
575     ;; Make " a punctuation character so highlighing works withing html strings
576     (modify-syntax-entry ?\" "." smarty-mode-syntax-table)
577     ;; define parentheses to match
578     (modify-syntax-entry ?\( "()"   smarty-mode-syntax-table)
579     (modify-syntax-entry ?\) ")("   smarty-mode-syntax-table)
580     (modify-syntax-entry ?\[ "(]"   smarty-mode-syntax-table)
581     (modify-syntax-entry ?\] ")["   smarty-mode-syntax-table)
582     (modify-syntax-entry ?\{ "(}"   smarty-mode-syntax-table)
583     (modify-syntax-entry ?\} "){"   smarty-mode-syntax-table)
584     )
585   (set-syntax-table smarty-mode-syntax-table)
586   ;; extended syntax table including '_' (for simpler search regexps)
587   (setq smarty-mode-ext-syntax-table (copy-syntax-table smarty-mode-syntax-table))
588   (modify-syntax-entry ?_ "w" smarty-mode-ext-syntax-table))
589
590 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
591 ;; File/directory manipulation
592 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
593
594 (defun smarty-directory-files (directory &optional full match)
595   "Call `directory-files' if DIRECTORY exists, otherwise generate error
596 message."
597   (if (not (file-directory-p directory))
598       (smarty-warning-when-idle "No such directory: \"%s\"" directory)
599     (let ((dir (directory-files directory full match)))
600       (setq dir (delete "." dir))
601       (setq dir (delete ".." dir))
602       dir)))
603
604 (defun smarty-get-source-files (&optional full directory)
605   "Get list of SMARTY source files in DIRECTORY or current directory."
606   (let ((mode-alist auto-mode-alist)
607         filename-regexp)
608     ;; create regular expressions for matching file names
609     (setq filename-regexp "\\`[^.].*\\(")
610     (while mode-alist
611       (when (eq (cdar mode-alist) 'smarty-mode)
612         (setq filename-regexp
613               (concat filename-regexp (caar mode-alist) "\\|")))
614       (setq mode-alist (cdr mode-alist)))
615     (setq filename-regexp
616           (concat (substring filename-regexp 0
617                              (string-match "\\\\|$" filename-regexp)) "\\)"))
618     ;; find files
619     (smarty-directory-files
620      (or directory default-directory) full filename-regexp)))
621
622 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
623 ;; Messages reporting
624 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
625
626 (defvar smarty-warnings nil
627   "Warnings to tell the user during start up.")
628
629 (defun smarty-run-when-idle (secs repeat function)
630   "Wait until idle, then run FUNCTION."
631   (if (fboundp 'start-itimer)
632       (start-itimer "smarty-mode" function secs repeat t)
633 ;    (run-with-idle-timer secs repeat function)))
634     ;; explicitely activate timer (necessary when Emacs is already idle)
635     (aset (run-with-idle-timer secs repeat function) 0 nil)))
636
637 (defun smarty-warning-when-idle (&rest args)
638   "Wait until idle, then print out warning STRING and beep."
639   (save-match-data ;; runs in timer
640     (if noninteractive
641         (smarty-warning (apply 'format args) t)
642       (unless smarty-warnings
643         (smarty-run-when-idle .1 nil 'smarty-print-warnings))
644       (setq smarty-warnings (cons (apply 'format args) smarty-warnings)))))
645
646 (defun smarty-warning (string &optional nobeep)
647   "Print out warning STRING and beep."
648   (message (concat "WARNING:  " string))
649   (unless (or nobeep noninteractive) (beep)))
650
651 (defun smarty-print-warnings ()
652   "Print out messages in variable `smarty-warnings'."
653   (let ((no-warnings (length smarty-warnings)))
654     (setq smarty-warnings (nreverse smarty-warnings))
655     (while smarty-warnings
656       (message (concat "WARNING:  " (car smarty-warnings)))
657       (setq smarty-warnings (cdr smarty-warnings)))
658     (beep)
659     (when (> no-warnings 1)
660       (message "WARNING:  See warnings in message buffer (type `C-c M-m')."))))
661
662 (defun smarty-show-messages ()
663   "Get *Messages* buffer to show recent messages."
664   (interactive)
665   (display-buffer " *Message-Log*"))
666
667 (defun smarty-version ()
668   "Echo the current version of Smarty Mode in the minibuffer."
669   (interactive)
670   (message "Smarty Mode %s (%s)" smarty-version smarty-time-stamp)
671   (smarty-keep-region-active))
672
673 ;; active regions
674 (defun smarty-keep-region-active ()
675   "Do whatever is necessary to keep the region active in XEmacs.
676 Ignore byte-compiler warnings you might see."
677   (and (boundp 'zmacs-region-stays)
678        (setq zmacs-region-stays t)))
679
680 (defmacro smarty-prepare-search-1 (&rest body)
681   "Enable case insensitive search and switch to syntax table that includes '_',
682 then execute BODY, and finally restore the old environment.  Used for
683 consistent searching."
684   `(let ((case-fold-search t)           ; case insensitive search
685          (current-syntax-table (syntax-table))
686          result
687          (restore-prog                  ; program to restore enviroment
688           '(progn
689              ;; restore syntax table
690              (set-syntax-table current-syntax-table))))
691      ;; use extended syntax table
692      (set-syntax-table smarty-mode-ext-syntax-table)
693      ;; execute BODY safely
694      (setq result
695            (condition-case info
696                (progn ,@body)
697              (error (eval restore-prog) ; restore environment on error
698                     (error (cadr info))))) ; pass error up
699      ;; restore environment
700      (eval restore-prog)
701      result))
702
703 (defmacro smarty-prepare-search-2 (&rest body)
704   "Enable case insensitive search, switch to syntax table that includes '_',
705 and remove `intangible' overlays, then execute BODY, and finally restore the
706 old environment.  Used for consistent searching."
707   `(let ((case-fold-search t)           ; case insensitive search
708          (current-syntax-table (syntax-table))
709          result overlay-all-list overlay-intangible-list overlay
710          (restore-prog                  ; program to restore enviroment
711           '(progn
712              ;; restore syntax table
713              (set-syntax-table current-syntax-table)
714              ;; restore `intangible' overlays
715              (when (fboundp 'overlay-lists)
716                (while overlay-intangible-list
717                  (overlay-put (car overlay-intangible-list) 'intangible t)
718                  (setq overlay-intangible-list
719                        (cdr overlay-intangible-list)))))))
720      ;; use extended syntax table
721      (set-syntax-table smarty-mode-ext-syntax-table)
722      ;; remove `intangible' overlays
723      (when (fboundp 'overlay-lists)
724        (setq overlay-all-list (overlay-lists))
725        (setq overlay-all-list
726              (append (car overlay-all-list) (cdr overlay-all-list)))
727        (while overlay-all-list
728          (setq overlay (car overlay-all-list))
729          (when (memq 'intangible (overlay-properties overlay))
730            (setq overlay-intangible-list
731                  (cons overlay overlay-intangible-list))
732            (overlay-put overlay 'intangible nil))
733          (setq overlay-all-list (cdr overlay-all-list))))
734      ;; execute BODY safely
735      (setq result
736            (condition-case info
737                (progn ,@body)
738              (error (eval restore-prog) ; restore environment on error
739                     (error (cadr info))))) ; pass error up
740      ;; restore environment
741      (eval restore-prog)
742      result))
743
744 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
745 ;;  Enabling/disabling
746
747 (defun smarty-mode-line-update ()
748   "Update the modeline string for Smarty major mode."
749   (setq mode-name (concat "Smarty"
750                           (and (or smarty-electric-mode smarty-stutter-mode) "/")
751                           (and smarty-electric-mode "e")
752                           (and smarty-stutter-mode "s")))
753   (force-mode-line-update t))
754
755 (defun smarty-electric-mode (arg)
756   "Toggle Smarty electric mode.
757 Turn on if ARG positive, turn off if ARG negative, toggle if ARG zero or nil."
758   (interactive "P")
759   (setq smarty-electric-mode
760         (cond ((or (not arg) (zerop arg)) (not smarty-electric-mode))
761               ((> arg 0) t) (t nil)))
762   (smarty-mode-line-update))
763
764 (defun smarty-stutter-mode (arg)
765   "Toggle Smarty stuttering mode.
766 Turn on if ARG positive, turn off if ARG negative, toggle if ARG zero or nil."
767   (interactive "P")
768   (setq smarty-stutter-mode
769         (cond ((or (not arg) (zerop arg)) (not smarty-stutter-mode))
770               ((> arg 0) t) (t nil)))
771   (smarty-mode-line-update))
772
773 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
774 ;;; Smarty code delimitation
775 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
776
777 (defun smarty-in-literal ()
778   "Determine if point is in a Smarty literal."
779   (save-excursion
780     (let ((here (point))
781           start state)
782       (beginning-of-line)
783       (setq start (point))
784       (goto-char here)
785       (setq state (parse-partial-sexp start (point)))
786       (cond
787        ((nth 3 state) 'string)
788        ((nth 4 state) 'comment)
789        (t nil)))))
790
791 (defun smarty-in-comment-p ()
792   "Check if point is in a comment."
793   (let ((result nil) (here (point-marker)) found)
794     (save-excursion
795       (setq found (re-search-backward (regexp-quote (concat smarty-left-delimiter "*")) nil t))
796       (when found
797         (setq result (re-search-forward (regexp-quote (concat "*" smarty-right-delimiter)) here t))
798         (setq result (not result))))
799     result))
800
801 (defun smarty-after-ldelim ()
802   "Check that the previous character is the left delimiter."
803   (let ((here (point-marker)) ldelim-found ldelim-point)
804     (save-excursion
805       (setq ldelim-found (re-search-backward (regexp-quote smarty-left-delimiter) nil t))
806       (re-search-forward (regexp-quote smarty-left-delimiter) here t)
807       (setq ldelim-point (point-marker))
808       (goto-char here)
809       (if (and (= here ldelim-point) ldelim-found)
810           t
811         nil))))
812
813 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
814 ;; Words to expand
815 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
816
817 (defun smarty-words-init ()
818   "Initialize reserved words."
819   (setq smarty-functions smarty-01-functions)
820   (setq smarty-modifiers smarty-01-modifiers)
821   (setq smarty-plugins-functions smarty-01-plugins-functions)
822   (setq smarty-plugins-modifiers smarty-01-plugins-modifiers)
823   (setq smarty-functions-regexp (concat "\\<\\(" (regexp-opt smarty-functions) "\\)\\>"))
824   (setq smarty-modifiers-regexp (concat "\\<\\(" (regexp-opt smarty-modifiers) "\\)\\>"))
825   (setq smarty-plugins-functions-regexp (concat "\\<\\(" (regexp-opt smarty-plugins-functions) "\\)\\>"))
826   (setq smarty-plugins-modifiers-regexp (concat "\\<\\(" (regexp-opt smarty-plugins-modifiers) "\\)\\>"))
827   (smarty-abbrev-list-init))
828
829 (defvar smarty-abbrev-list nil
830   "Predefined abbreviations for Smarty.")
831
832 (defun smarty-abbrev-list-init ()
833   (setq smarty-abbrev-list
834         (append
835          (list nil) smarty-functions
836          (list nil) smarty-modifiers
837          (list nil) smarty-plugins-functions
838          (list nil) smarty-plugins-modifiers)))
839
840 (defvar smarty-expand-upper-case nil)
841
842 (defun smarty-try-expand-abbrev (old)
843   "Try expanding abbreviations from `smarty-abbrev-list'."
844   (unless old
845     (he-init-string (he-dabbrev-beg) (point))
846     (setq he-expand-list
847           (let ((abbrev-list smarty-abbrev-list)
848                 (sel-abbrev-list '()))
849             (while abbrev-list
850            ;   (if (stringp (car abbrev-list))
851                 ;  (insert (concat " " (car abbrev-list))))
852               (when (or (not (stringp (car abbrev-list)))
853                         (string-match
854                          (concat "^" he-search-string) (car abbrev-list)))
855                 (setq sel-abbrev-list
856                       (cons (car abbrev-list) sel-abbrev-list)))
857               (setq abbrev-list (cdr abbrev-list)))
858             (nreverse sel-abbrev-list))))
859   (while (and he-expand-list
860               (or (not (stringp (car he-expand-list)))
861                   (he-string-member (car he-expand-list) he-tried-table t)))
862     (unless (stringp (car he-expand-list))
863       (setq smarty-expand-upper-case (car he-expand-list)))
864     (setq he-expand-list (cdr he-expand-list)))
865   (if (null he-expand-list)
866       (progn (when old (he-reset-string))
867              nil)
868     (he-substitute-string
869      (if smarty-expand-upper-case
870          (upcase (car he-expand-list))
871        (car he-expand-list))
872      t)
873     (setq he-expand-list (cdr he-expand-list))
874     t))
875
876 ;; initialize reserved words for Smarty Mode
877 (smarty-words-init)
878
879 ;; function for expanding abbrevs and dabbrevs
880 (defun smarty-expand-abbrev (arg))
881 (fset 'smarty-expand-abbrev (make-hippie-expand-function
882                            '(try-expand-dabbrev
883                              try-expand-dabbrev-all-buffers
884                              smarty-try-expand-abbrev)))
885
886 ;; function for expanding parenthesis
887 (defun smarty-expand-paren (arg))
888 (fset 'smarty-expand-paren (make-hippie-expand-function
889                           '(try-expand-list
890                             try-expand-list-all-buffers)))
891
892 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
893 ;;; Stuttering
894 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
895
896 (defvar smarty-end-comment-column 80)
897
898 (defvar found) ;; silence compiler, dyn var
899
900 (defun smarty-electric-tab (&optional prefix-arg)
901   "If preceding character is part of a word or a paren then hippie-expand,
902 else if right of non whitespace on line then insert tab,
903 else if last command was a tab or return then dedent one step or if a comment
904 toggle between normal indent and inline comment indent,
905 else indent `correctly'."
906   (interactive "*P")
907   (smarty-prepare-search-2
908    (cond
909     ;; expand word
910     ((= (char-syntax (preceding-char)) ?w)
911      (let ((case-fold-search (not smarty-word-completion-case-sensitive))
912            (case-replace nil)
913            (hippie-expand-only-buffers
914             (or (and (boundp 'hippie-expand-only-buffers)
915                      hippie-expand-only-buffers)
916                 '(smarty-mode))))
917        (smarty-expand-abbrev prefix-arg)))
918     ;; expand parenthesis
919     ((or (= (preceding-char) ?\() (= (preceding-char) ?\)))
920      (let ((case-fold-search (not smarty-word-completion-case-sensitive))
921            (case-replace nil))
922        (smarty-expand-paren prefix-arg))))
923    (setq this-command 'smarty-electric-tab)))
924
925 (defun smarty-electric-space (count)
926   "Expand abbreviations and self-insert space(s)."
927   (interactive "p")
928   (let ((here (point-marker)) ldelim-found ldelim-point rdelim-found rdelim-point
929         delete-a)
930     (setq ldelim-found (re-search-backward (regexp-quote smarty-left-delimiter) nil t))
931     (re-search-forward (regexp-quote smarty-left-delimiter) here t)
932     (setq ldelim-point (point-marker))
933     (goto-char here)
934     (setq rdelim-found (re-search-backward (regexp-quote (concat " " smarty-right-delimiter)) nil t))
935     (re-search-forward (regexp-quote (concat " " smarty-right-delimiter)) here t)
936     (setq rdelim-point (point-marker))
937     (goto-char here)
938   (cond ((and (= here ldelim-point) ldelim-found) (insert (concat "ldelim" smarty-right-delimiter)))
939         ((and (= here rdelim-point) rdelim-found)
940          (re-search-backward (regexp-quote (concat " " smarty-right-delimiter)) nil t)
941          (delete-char 1)
942          (insert (concat " " smarty-left-delimiter "rdelim"))
943          (goto-char here))
944         ((smarty-in-comment-p)
945          (self-insert-command count)
946          (cond ((>= (current-column) (+ 2 smarty-end-comment-column))
947                 (backward-char 1)
948                 (skip-chars-backward "^ \t\n")
949                 (indent-new-comment-line)
950                 (skip-chars-forward "^ \t\n")
951                 (forward-char 1))
952                ((>= (current-column) smarty-end-comment-column)
953                 (indent-new-comment-line))
954                (t nil)))
955         ((or (and (>= (preceding-char) ?a) (<= (preceding-char) ?z))
956              (and (>= (preceding-char) ?A) (<= (preceding-char) ?Z))
957              (and (>= (preceding-char) ?0) (<= (preceding-char) ?9)))
958          (progn
959            (setq here (point-marker))
960            (insert " ")
961            (setq delete-a t)
962            (if (re-search-backward "|" nil t)
963                (progn
964                  (setq found (re-search-forward (regexp-quote "B2Smilies") here t))
965                  (if (and found (= here (point-marker)))
966                      (replace-match "btosmilies")
967                    (setq found (re-search-forward (regexp-quote "bbcode2html") here t))
968                    (if (and found (= here (point-marker)))
969                        (replace-match "bbcodetohtml")
970                      (setq found (re-search-forward (regexp-quote "date_format2") here t))
971                      (if (and found (= here (point-marker)))
972                          (replace-match "date_formatto")
973                        (goto-char here)
974                        (setq delete-a nil)
975                        (delete-char 1)))))
976              (goto-char here)
977              (setq delete-a nil)
978              (delete-char 1)))
979          (smarty-prepare-search-1 (expand-abbrev))
980          (self-insert-command count)
981          (if (and delete-a (looking-at " "))
982              (delete-char 1)))
983         (t (self-insert-command count)))))
984
985 (defun smarty-electric-open-bracket (count)
986   "'(' --> '(', '((' --> '[', '[(' --> '{'"
987   (interactive "p")
988   (if (and smarty-stutter-mode (= count 1) (not (smarty-in-literal)))
989       (if (= (preceding-char) ?\()
990           (progn (delete-char -1) (insert-char ?\[ 1))
991         (if (= (preceding-char) ?\[)
992             (progn (delete-char -1) (insert-char ?\{ 1))
993           (insert-char ?\( 1)))
994     (self-insert-command count)))
995
996 (defun smarty-electric-close-bracket (count)
997   "')' --> ')', '))' --> ']', '])' --> '}'"
998   (interactive "p")
999   (if (and smarty-stutter-mode (= count 1) (not (smarty-in-literal)))
1000       (progn
1001         (if (= (preceding-char) ?\))
1002             (progn (delete-char -1) (insert-char ?\] 1))
1003           (if (= (preceding-char) ?\])
1004               (progn (delete-char -1) (insert-char ?} 1))
1005             (insert-char ?\) 1)))
1006         (blink-matching-open))
1007     (self-insert-command count)))
1008
1009 (defun smarty-electric-star (count)
1010   "After a left delimiter add a right delemiter to close the comment"
1011   (interactive "p")
1012   (let ((here (point-marker)) found)
1013     (if (and smarty-stutter-mode (= count 1) (not (smarty-in-literal)))
1014         (progn
1015           (setq found (re-search-backward (regexp-quote smarty-left-delimiter) nil t))
1016           (re-search-forward (regexp-quote smarty-left-delimiter) here t)
1017           (if (not (and (= here (point-marker)) found))
1018               (progn (goto-char here)
1019                      (self-insert-command count))
1020             (self-insert-command count)
1021             (insert " ")
1022             (setq here (point-marker))
1023             (insert " *")
1024             (insert smarty-right-delimiter)
1025             (goto-char here)))
1026       (self-insert-command count))))
1027
1028 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1029 ;;; Electrification
1030 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1031
1032 (defconst smarty-template-prompt-syntax "[^ =<>][^<>@.\n]*[^ =<>]"
1033   "Syntax of prompt inserted by template generators.")
1034
1035 (defvar smarty-template-invoked-by-hook nil
1036   "Indicates whether a template has been invoked by a hook or by key or menu.
1037 Used for undoing after template abortion.")
1038
1039 (defun smarty-minibuffer-tab (&optional prefix-arg)
1040   "If preceding character is part of a word or a paren then hippie-expand,
1041 else insert tab (used for word completion in Smarty minibuffer)."
1042   (interactive "P")
1043   (cond
1044    ;; expand word
1045    ((= (char-syntax (preceding-char)) ?w)
1046     (let ((case-fold-search (not smarty-word-completion-case-sensitive))
1047           (case-replace nil)
1048           (hippie-expand-only-buffers
1049            (or (and (boundp 'hippie-expand-only-buffers)
1050                     hippie-expand-only-buffers)
1051                '(smarty-mode))))
1052       (smarty-expand-abbrev prefix-arg)))
1053    ;; expand parenthesis
1054    ((or (= (preceding-char) ?\() (= (preceding-char) ?\)))
1055     (let ((case-fold-search (not smarty-word-completion-case-sensitive))
1056           (case-replace nil))
1057       (smarty-expand-paren prefix-arg)))
1058    ;; insert tab
1059    (t (insert-tab))))
1060
1061 ;; correct different behavior of function `unread-command-events' in XEmacs
1062 (defun smarty-character-to-event (arg))
1063 (defalias 'smarty-character-to-event
1064   (if (fboundp 'character-to-event) 'character-to-event 'identity))
1065
1066 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1067 ;; Abbrev ook bindings
1068 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1069
1070 (defvar smarty-mode-abbrev-table nil
1071   "Abbrev table to use in `smarty-mode' buffers.")
1072
1073 (defun smarty-mode-abbrev-table-init ()
1074   "Initialize `smarty-mode-abbrev-table'."
1075   (when smarty-mode-abbrev-table (clear-abbrev-table smarty-mode-abbrev-table))
1076   (define-abbrev-table 'smarty-mode-abbrev-table
1077     (append
1078      '(
1079        ("capture" "" smarty-template-capture-hook 0)
1080        ("config_load" "" smarty-template-config-load-hook 0)
1081        ("else" "" smarty-template-else-hook 0)
1082        ("elseif" "" smarty-template-elseif-hook 0)
1083        ("foreach" "" smarty-template-foreach-hook 0)
1084        ("foreachelse" "" smarty-template-foreachelse-hook 0)
1085        ("if" "" smarty-template-if-hook 0)
1086        ("include" "" smarty-template-include-hook 0)
1087        ("include_php" "" smarty-template-include-php-hook 0)
1088        ("insert" "" smarty-template-insert-hook 0)
1089        ("ldelim" "" smarty-template-ldelim-hook 0)
1090        ("literal" "" smarty-template-literal-hook 0)
1091        ("php" "" smarty-template-php-hook 0)
1092        ("rdelim" "" smarty-template-rdelim-hook 0)
1093        ("section" "" smarty-template-section-hook 0)
1094        ("sectionelse" "" smarty-template-sectionelse-hook 0)
1095        ("strip" "" smarty-template-strip-hook 0)
1096        ("assign" "" smarty-template-assign-hook 0)
1097        ("counter" "" smarty-template-counter-hook 0)
1098        ("cycle" "" smarty-template-cycle-hook 0)
1099        ("debug" "" smarty-template-debug-hook 0)
1100        ("eval" "" smarty-template-eval-hook 0)
1101        ("fetch" ""  smarty-template-fetch-hook 0)
1102        ("html_checkboxes" "" smarty-template-html-checkboxes-hook 0)
1103        ("html_image" "" smarty-template-html-image-hook 0)
1104        ("html_options" "" smarty-template-html-options-hook 0)
1105        ("html_radios" "" smarty-template-html-radios-hook 0)
1106        ("html_select_date" "" smarty-template-html-select-date-hook 0)
1107        ("html_select_time" "" smarty-template-html-select-time-hook 0)
1108        ("html_table" "" smarty-template-html-table-hook 0)
1109        ("mailto" "" smarty-template-mailto-hook 0)
1110        ("math" "" smarty-template-math-hook 0)
1111        ("popup" "" smarty-template-popup-hook 0)
1112        ("popup_init" "" smarty-template-popup-init-hook 0)
1113        ("textformat" "" smarty-template-textformat-hook 0)
1114        ("capitalize" "" smarty-template-capitalize-hook 0)
1115        ("cat" "" smarty-template-cat-hook 0)
1116        ("count_characters" "" smarty-template-count-characters-hook 0)
1117        ("count_paragraphs" "" smarty-template-count-paragraphs-hook 0)
1118        ("count_sentences" "" smarty-template-count-sentences-hook 0)
1119        ("count_words" "" smarty-template-count-words-hook 0)
1120        ("date_format" "" smarty-template-date-format-hook 0)
1121        ("default" "" smarty-template-default-hook 0)
1122        ("escape" "" smarty-template-escape-hook 0)
1123        ("indent" "" smarty-template-indent-hook 0)
1124        ("lower" "" smarty-template-lower-hook 0)
1125        ("nl2br" "" smarty-template-nl2br-hook 0)
1126        ("regex_replace" "" smarty-template-regex-replace-hook 0)
1127        ("replace" "" smarty-template-replace-hook 0)
1128        ("spacify" "" smarty-template-spacify-hook 0)
1129        ("string_format" "" smarty-template-string-format-hook 0)
1130        ("strip" "" smarty-template-vstrip-hook 0)
1131        ("strip_tags" "" smarty-template-strip-tags-hook 0)
1132        ("truncate" "" smarty-template-truncate-hook 0)
1133        ("upper" "" smarty-template-upper-hook 0)
1134        ("wordwrap" "" smarty-template-wordwrap-hook 0)
1135        ("validate" "" smarty-template-validate-hook 0)
1136        ("clipcache" "" smarty-template-clipcache-hook 0)
1137        ("repeat" "" smarty-template-repeat-hook 0)
1138        ("str_repeat" "" smarty-template-str-repeat-hook 0)
1139        ("include_clipcache" "" smarty-template-include-clipcache-hook 0)
1140        ("formtool_checkall" "" smarty-template-formtool-checkall-hook 0)
1141        ("formtool_copy" "" smarty-template-formtool-copy-hook 0)
1142        ("formtool_count_chars" "" smarty-template-formtool-count-chars-hook 0)
1143        ("formtool_init" "" smarty-template-formtool-init-hook 0)
1144        ("formtool_move" "" smarty-template-formtool-move-hook 0)
1145        ("formtool_moveall" "" smarty-template-formtool-moveall-hook 0)
1146        ("formtool_movedown" "" smarty-template-formtool-movedown-hook 0)
1147        ("formtool_moveup" "" smarty-template-formtool-moveup-hook 0)
1148        ("formtool_remove" "" smarty-template-formtool-remove-hook 0)
1149        ("formtool_rename" "" smarty-template-formtool-rename-hook 0)
1150        ("formtool_save" "" smarty-template-formtool-save-hook 0)
1151        ("formtool_selectall" "" smarty-template-formtool-selectall-hook 0)
1152        ("paginate_first" "" smarty-template-paginate-first-hook 0)
1153        ("paginate_last" "" smarty-template-paginate-last-hook 0)
1154        ("paginate_middle" "" smarty-template-paginate-middle-hook 0)
1155        ("paginate_next" "" smarty-template-paginate-next-hook 0)
1156        ("paginate_prev" "" smarty-template-paginate-prev-hook 0)
1157        ("btosmilies" "" smarty-template-btosmilies-hook 0)
1158        ("bbcodetohtml" "" smarty-template-bbcodetohtml-hook 0)
1159        ("date_formatto" "" smarty-template-date-formatto-hook 0)))))
1160
1161 ;; initialize abbrev table for Smarty Mode
1162 (smarty-mode-abbrev-table-init)
1163
1164 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1165 ;; Abbrev hooks
1166 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1167
1168 (defun smarty-hooked-abbrev (func)
1169   "Do function, if syntax says abbrev is a keyword, invoked by hooked abbrev,
1170 but not if inside a comment or quote)."
1171   (if (or (smarty-in-literal)
1172           (smarty-in-comment-p))
1173       (progn
1174         (insert " ")
1175         (unexpand-abbrev)
1176         (delete-char -1))
1177     (if (not smarty-electric-mode)
1178         (progn
1179           (insert " ")
1180           (unexpand-abbrev)
1181           (backward-word 1)
1182           (delete-char 1))
1183       (let ((invoke-char last-command-event)
1184             (abbrev-mode -1)
1185             (smarty-template-invoked-by-hook t))
1186         (let ((caught (catch 'abort
1187                         (funcall func))))
1188           (when (stringp caught) (message caught)))
1189         (when (= invoke-char ?-) (setq abbrev-start-location (point)))
1190         ;; delete CR which is still in event queue
1191         (if (fboundp 'enqueue-eval-event)
1192             (enqueue-eval-event 'delete-char -1)
1193           (setq unread-command-events   ; push back a delete char
1194                 (list (smarty-character-to-event ?\177))))))))
1195
1196 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1197 ;;; Fontification
1198 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1199
1200 (defvar smarty-font-lock-keywords-1
1201   (list
1202
1203    ;; Fontify built-in functions
1204    (cons
1205         (concat (regexp-quote smarty-left-delimiter) "[/]*" smarty-functions-regexp)
1206         '(1 font-lock-keyword-face))
1207
1208    (cons
1209         (concat "\\<\\(" smarty-constants "\\)\\>")
1210         'font-lock-constant-face)
1211
1212    (cons (concat "\\(" (regexp-quote (concat smarty-left-delimiter "*")) "\\(\\s-\\|\\w\\|\\s.\\|\\s_\\|\\s(\\|\\s)\\|\\s\\\\)*" (regexp-quote (concat "*" smarty-right-delimiter)) "\\)")
1213          'font-lock-comment-face)
1214
1215    )
1216   "Subdued level highlighting for Smarty mode.")
1217
1218 (defconst smarty-font-lock-keywords-2
1219   (append
1220    smarty-font-lock-keywords-1
1221    (list
1222
1223         ;; Fontify variable names (\\sw\\|\\s_\\) matches any word character +
1224         ;; underscore
1225         '("\\$\\(\\(?:\\sw\\|\\s_\\)+\\)" (1 font-lock-variable-name-face)) ; $variable
1226         '("->\\(\\(?:\\sw\\|\\s_\\)+\\)" (1 font-lock-variable-name-face t t)) ; ->variable
1227         '("\\.\\(\\(?:\\sw\\|\\s_\\)+\\)" (1 font-lock-variable-name-face t t)) ; .variable
1228         '("->\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(" (1 font-lock-function-name-face t t)) ; ->function_call
1229         '("\\<\\(\\(?:\\sw\\|\\s_\\)+\\s-*\\)(" (1 font-lock-function-name-face)) ; word(
1230         '("\\<\\(\\(?:\\sw\\|\\s_\\)+\\s-*\\)[[]" (1 font-lock-variable-name-face)) ; word[
1231         '("\\<[0-9]+" . 'default)                       ; number (also matches word)
1232
1233         ;; Fontify strings
1234         ;;'("\"\\([^\"]*\\)\"[^\"]+" (1 font-lock-string-face t t))
1235         ))
1236
1237    "Medium level highlighting for Smarty mode.")
1238
1239 (defconst smarty-font-lock-keywords-3
1240   (append
1241    smarty-font-lock-keywords-2
1242    (list
1243     ;; Fontify modifiers
1244     (cons (concat "|\\(" smarty-modifiers-regexp "\\)[:|]+") '(1 font-lock-function-name-face))
1245     (cons (concat "|\\(" smarty-modifiers-regexp "\\)" (regexp-quote smarty-right-delimiter)) '(1 font-lock-function-name-face))
1246
1247     ;; Fontify config vars
1248     (cons (concat (regexp-quote smarty-left-delimiter) "\\(#\\(?:\\sw\\|\\s_\\)+#\\)") '(1 font-lock-constant-face))))
1249   "Balls-out highlighting for Smarty mode.")
1250
1251 (defconst smarty-font-lock-keywords-4
1252   (append
1253    smarty-font-lock-keywords-3
1254    (list
1255     ;; Fontify plugin functions
1256     (cons
1257      (concat (regexp-quote smarty-left-delimiter) "[/]*" smarty-plugins-functions-regexp)
1258      '(1 font-lock-keyword-face))
1259
1260     (cons (concat "|\\(" smarty-plugins-modifiers-regexp "\\)[:|]+") '(1 font-lock-function-name-face))
1261     (cons (concat "|\\(" smarty-plugins-modifiers-regexp "\\)" (regexp-quote smarty-right-delimiter)) '(1 font-lock-function-name-face)))))
1262
1263 (defvar smarty-font-lock-keywords smarty-font-lock-keywords-3
1264   "Default highlighting level for Smarty mode")
1265
1266 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1267 ;;; Mode map
1268 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1269
1270 (defvar smarty-template-map nil
1271   "Keymap for Smarty templates.")
1272
1273 (defun smarty-template-map-init ()
1274   "Initialize `smarty-template-map'."
1275   (setq smarty-template-map (make-sparse-keymap))
1276   ;; key bindings for Smarty templates
1277   (define-key smarty-template-map "\C-ba" 'smarty-template-capture)
1278   (define-key smarty-template-map "\C-bc" 'smarty-template-config-load)
1279   (define-key smarty-template-map "\C-b\M-e" 'smarty-template-else)
1280   (define-key smarty-template-map "\C-b\C-e" 'smarty-template-elseif)
1281   (define-key smarty-template-map "\C-b\C-f" 'smarty-template-foreach)
1282   (define-key smarty-template-map "\C-b\M-f" 'smarty-template-foreachelse)
1283   (define-key smarty-template-map "\C-bf" 'smarty-template-if)
1284   (define-key smarty-template-map "\C-b\C-i" 'smarty-template-include)
1285   (define-key smarty-template-map "\C-b\M-i" 'smarty-template-include-php)
1286   (define-key smarty-template-map "\C-bi" 'smarty-template-insert)
1287   (define-key smarty-template-map "\C-bl" 'smarty-template-ldelim)
1288   (define-key smarty-template-map "\C-b\C-l" 'smarty-template-literal)
1289   (define-key smarty-template-map "\C-bp" 'smarty-template-php)
1290   (define-key smarty-template-map "\C-br" 'smarty-template-rdelim)
1291   (define-key smarty-template-map "\C-b\C-s" 'smarty-template-section)
1292   (define-key smarty-template-map "\C-b\M-s" 'smarty-template-sectionelse)
1293   (define-key smarty-template-map "\C-bs" 'smarty-template-strip)
1294   (define-key smarty-template-map "\C-ca" 'smarty-template-assign)
1295   (define-key smarty-template-map "\C-co" 'smarty-template-counter)
1296   (define-key smarty-template-map "\C-cc" 'smarty-template-cycle)
1297   (define-key smarty-template-map "\C-cd" 'smarty-template-debug)
1298   (define-key smarty-template-map "\C-ce" 'smarty-template-eval)
1299   (define-key smarty-template-map "\C-cf" 'smarty-template-fetch)
1300   (define-key smarty-template-map "\C-c\C-hc" 'smarty-template-html-checkboxes)
1301   (define-key smarty-template-map "\C-c\C-hi" 'smarty-template-html-image)
1302   (define-key smarty-template-map "\C-c\C-ho" 'smarty-template-html-options)
1303   (define-key smarty-template-map "\C-c\C-hr" 'smarty-template-html-radios)
1304   (define-key smarty-template-map "\C-c\C-hd" 'smarty-template-html-select-date)
1305   (define-key smarty-template-map "\C-c\C-hm" 'smarty-template-html-select-time)
1306   (define-key smarty-template-map "\C-c\C-ht" 'smarty-template-html-table)
1307   (define-key smarty-template-map "\C-ci" 'smarty-template-mailto)
1308   (define-key smarty-template-map "\C-ch" 'smarty-template-math)
1309   (define-key smarty-template-map "\C-c\C-p" 'smarty-template-popup)
1310   (define-key smarty-template-map "\C-c\M-p" 'smarty-template-popup-init)
1311   (define-key smarty-template-map "\C-ct" 'smarty-template-textformat)
1312   (define-key smarty-template-map "\C-vp" 'smarty-template-capitalize)
1313   (define-key smarty-template-map "\C-vc" 'smarty-template-cat)
1314   (define-key smarty-template-map "\C-v\C-cc" 'smarty-template-count-characters)
1315   (define-key smarty-template-map "\C-v\C-cp" 'smarty-template-count-paragraphs)
1316   (define-key smarty-template-map "\C-v\C-cs" 'smarty-template-count-sentences)
1317   (define-key smarty-template-map "\C-v\C-cw" 'smarty-template-count-words)
1318   (define-key smarty-template-map "\C-vf" 'smarty-template-date-format)
1319   (define-key smarty-template-map "\C-vd" 'smarty-template-default)
1320   (define-key smarty-template-map "\C-ve" 'smarty-template-escape)
1321   (define-key smarty-template-map "\C-vi" 'smarty-template-indent)
1322   (define-key smarty-template-map "\C-vl" 'smarty-template-lower)
1323   (define-key smarty-template-map "\C-vn" 'smarty-template-nl2br)
1324   (define-key smarty-template-map "\C-vx" 'smarty-template-regex-replace)
1325   (define-key smarty-template-map "\C-v\C-p" 'smarty-template-replace)
1326   (define-key smarty-template-map "\C-vy" 'smarty-template-spacify)
1327   (define-key smarty-template-map "\C-vs" 'smarty-template-string-format)
1328   (define-key smarty-template-map "\C-v\C-s" 'smarty-template-vstrip)
1329   (define-key smarty-template-map "\C-v\M-s" 'smarty-template-strip-tags)
1330   (define-key smarty-template-map "\C-vt" 'smarty-template-truncate)
1331   (define-key smarty-template-map "\C-vu" 'smarty-template-upper)
1332   (define-key smarty-template-map "\C-vw" 'smarty-template-wordwrap)
1333   (define-key smarty-template-map "\C-h" 'smarty-template-header)
1334   (define-key smarty-template-map "\C-f" 'smarty-template-footer)
1335   (define-key smarty-template-map "\C-di" 'smarty-template-insert-date)
1336   (define-key smarty-template-map "\C-dm" 'smarty-template-modify))
1337
1338 ;; initialize template map for Smarty Mode
1339 (smarty-template-map-init)
1340
1341 (defun smarty-mode-map-init ()
1342   "Initialize `smarty-mode-map'."
1343   (setq smarty-mode-map (make-sparse-keymap))
1344   ;; template key bindings
1345   (define-key smarty-mode-map "\C-c\C-t"   smarty-template-map)
1346   ;; mode specific key bindings
1347   (define-key smarty-mode-map "\C-c\C-m\C-e"  'smarty-electric-mode)
1348   (define-key smarty-mode-map "\C-c\C-m\C-s"  'smarty-stutter-mode)
1349   (define-key smarty-mode-map "\C-c\C-s\C-u"  'smarty-add-source-files-menu)
1350   (define-key smarty-mode-map "\C-c\M-m"   'smarty-show-messages)
1351   (define-key smarty-mode-map "\C-c\C-h"   'smarty-doc-mode)
1352   (define-key smarty-mode-map "\C-c\C-v"   'smarty-version)
1353   ;; electric key bindings
1354   (when smarty-intelligent-tab
1355     (define-key smarty-mode-map "\t" 'smarty-electric-tab))
1356   (define-key smarty-mode-map " " 'smarty-electric-space)
1357   (define-key smarty-mode-map "(" 'smarty-electric-open-bracket)
1358   (define-key smarty-mode-map ")" 'smarty-electric-close-bracket)
1359   (define-key smarty-mode-map "*" 'smarty-electric-star))
1360
1361 ;; initialize mode map for Smarty Mode
1362 (smarty-mode-map-init)
1363
1364 (defvar smarty-minibuffer-local-map
1365   (let ((map (make-sparse-keymap)))
1366     (set-keymap-parent map minibuffer-local-map)
1367     (when smarty-word-completion-in-minibuffer
1368       (define-key map "\t" 'smarty-minibuffer-tab))
1369     map)
1370   "Keymap for minibuffer used in Smarty Mode.")
1371
1372 (mapcar
1373  (function
1374   (lambda (sym)
1375     (put sym 'delete-selection t)       ; for `delete-selection-mode' (Emacs)
1376     (put sym 'pending-delete t)))       ; for `pending-delete-mode' (XEmacs)
1377  '(smarty-electric-space
1378    smarty-electric-tab
1379    smarty-electric-open-bracket
1380    smarty-electric-close-bracket
1381    smarty-electric-star))
1382
1383 ;;;###autoload
1384 (defun smarty-mode ()
1385   "Smarty Mode
1386 ***********
1387
1388 Smarty Mode is a GNU XEmacs major mode for editing Smarty templates.
1389
1390 1 Introduction
1391 **************
1392
1393 Smarty-Mode is a mode allowing easy edit of Smarty templates:
1394 highlight, templates, navigation into source files...
1395
1396
1397
1398 Features (new features in bold) :
1399
1400    * Completion
1401
1402    * Customizable
1403
1404    * Highlight
1405
1406    * Menu
1407
1408    * Stuttering
1409
1410    * Templates
1411         - Built-in Functions
1412
1413         - User Functions
1414
1415         - Variable Modifiers
1416
1417         - Plugin (Functions)
1418              * BlockRepeatPlugin
1419
1420              * ClipCache
1421
1422              * Smarty Formtool
1423
1424              * Smarty Paginate
1425
1426              * Smarty Validate
1427
1428         - Plugin (Variable Modifiers)
1429              * AlternativeDateModifierPlugin
1430
1431              * B2Smilies
1432
1433              * BBCodePlugin
1434
1435         - Fonctions Non-Smarty
1436
1437
1438
1439 This manual describes Smarty Mode version 0.0.5.
1440
1441 2 Installation
1442 **************
1443
1444 2.1 Requirements
1445 ================
1446
1447 Smarty Mode is a XEmacs major mode that needs the following
1448 software/packages:
1449
1450    * XEmacs (http://www.xemacs.org/).
1451
1452    * `font-lock' mode generaly installed with XEmacs.
1453
1454    * `assoc' mode generaly installed with XEmacs.
1455
1456    * `easymenu' mode generaly installed with XEmacs.
1457
1458    * `hippie-exp' mode generaly installed with XEmacs.
1459
1460 Before continuing, you must be sure to have all this packages
1461 installed.
1462
1463 2.2 Download
1464 ============
1465
1466 Two internet address to download Smarty Mode :
1467
1468    * Principal: Smarty-Mode 0.0.5
1469      (http://deboutv.free.fr/lisp/smarty/download/smarty-0.0.5.tar.gz)
1470      (http://deboutv.free.fr/lisp/smarty/)
1471
1472    * Secondary: Smarty-Mode 0.0.5
1473      (http://www.morinie.fr/lisp/smarty/download/smarty-0.0.5.tar.gz)
1474      (http://www.morinie.fr/lisp/smarty/)
1475
1476    * Old releases: Smarty-Mode
1477      (http://deboutv.free.fr/lisp/smarty/download.php)
1478      (http://deboutv.free.fr/lisp/smarty/)
1479
1480 2.3 Installation
1481 ================
1482
1483 2.3.1 Installation
1484 ------------------
1485
1486 To install Smarty Mode you need to choose an installation directory
1487 \(for example `/usr/local/share/lisp' or `c:\lisp'). The administrator
1488 must have the write rights on this directory.
1489
1490 With your favorite unzip software, unzip the archive in the
1491 installation directory.
1492
1493 Example:
1494      cd /usr/local/share/lisp
1495      tar zxvf smarty-0.0.5.tar.gz
1496 Now you have a `smarty' directory in the installation directory. This
1497 directory contains 2 files `smarty-mode.el' and `smarty-mode.elc' and
1498 another directory `docs' containing the documentation.
1499
1500 You need to configure XEmacs. open you initialization file `init.el'
1501 \(open the file or start XEmacs then choose the Options menu and Edit
1502 Init File). Add the following lines (the installation directory in
1503 this example is `/usr/local/share/lisp') :
1504
1505      (setq load-path
1506            (append (list \"/usr/local/share/lisp/\") load-path))
1507      (autoload 'smarty-mode \"smarty-mode\" \"Smarty Mode\" t)
1508
1509 2.3.2 Update
1510 ------------
1511
1512 The update is easy. You need to unzip the archive in the installation
1513 directory to remove the old release.
1514
1515 Example:
1516      cd /usr/local/share/lisp
1517      rm -rf smarty
1518      tar zxvf smarty-0.0.5.tar.gz
1519
1520 2.4 Invoke Smarty-Mode
1521 ======================
1522
1523 You have two possibilities to invoke the Smarty Mode.
1524
1525    - Manually: At each file opening you need to launch Smarty Mode
1526      with the following command:
1527
1528      `M-x smarty-mode'
1529
1530    - Automatically: Add the following linesin your initialization
1531      file `init.el' :
1532
1533           (setq auto-mode-alist
1534                 (append
1535                  '((\"\\.tpl$\" . smarty-mode))
1536                  auto-mode-alist))
1537
1538
1539 3 Customization
1540 ***************
1541
1542 This chapter describes the differents parameters and functions that
1543 you can change to customize Smarty Mode.  To do that, open a Smarty
1544 file, click on the Smarty menu and choose Options then Browse
1545 Options....
1546
1547 3.1 Parameters
1548 ==============
1549
1550 3.1.1 Mode
1551 ----------
1552
1553 Smarty Mode has 2 modes allowing to simplify the writing of Smarty
1554 templates. You can enable/disable each mode individually.
1555
1556 `smarty-electric-mode'
1557      Type: boolean
1558      Default value: `t'
1559      Description: If `t'; enable automatic generation of template.
1560      If `nil'; template generators can still be invoked through key
1561      bindings and menu. Is indicated in the modeline by \"/e\" after
1562      the mode name and can be toggled by `smarty-electric-mode'.
1563
1564 `smarty-stutter-mode'
1565      Type: boolean
1566      Default value: `t'
1567      Description: If `t'; enable the stuttering. Is indicated in the
1568      modeline by \"/s\" after the mode name and can be toggled by
1569      `smarty-stutter-mode'.
1570
1571 3.1.2 Menu
1572 ----------
1573
1574 Smarty Mode has also 1 menu that you can enable/disable. The menu
1575 Sources is specific to each Smarty files opened.
1576
1577 `smarty-source-file-menu'
1578      Type: boolean
1579      Default value: `t'
1580      Description: If `t'; the Sources menu is enabled. This menu
1581      contains the list of Smarty file located in the current
1582      directory. The Sources menu scans the directory when a file is
1583      opened.
1584
1585 3.1.3 Menu
1586 ----------
1587
1588 `smarty-highlight-plugin-functions'
1589      Type: boolean
1590      Default value: `t'
1591      Description: If `t'; the functions described in the smarty
1592      plugins are highlighted.
1593
1594 3.1.4 Templates
1595 ---------------
1596
1597 3.1.4.1 Header
1598 ..............
1599
1600 `smarty-file-header'
1601      Type: string
1602      Default value: `\"\"'
1603      Description: String or file to insert as file header. If the
1604      string specifies an existing file name the contents of the file
1605      is inserted; otherwise the string itself is inserted as file
1606      header.
1607      Type `C-j' for newlines.
1608      The follonwing keywords are supported:
1609      <filename>: replaced by the file name.
1610      <author>: replaced by the user name and email address.
1611      <login>: replaced by `user-login-name'.
1612      <company>: replaced by `smarty-company-name' content.
1613      <date>: replaced by the current date.
1614      <year>: replaced by the current year.
1615      <copyright>: replaced by `smarty-copyright-string' content.
1616      <cursor>: final cursor position.
1617
1618 `smarty-file-footer'
1619      Type: string
1620      Default value: `\"\"'
1621      Description: String or file to insert as file footer.  See
1622      `smarty-file-header'
1623
1624 `smarty-company-name'
1625      Type: string
1626      Default value: `\"\"'
1627      Description: Name of the company to insert in file header.
1628
1629 `smarty-copyright-string'
1630      Type: string
1631      Default value: `\"\"'
1632      Description: Coryright string to insert in file header.
1633
1634 `smarty-date-format'
1635      Type: string
1636      Default value: `\"%Y-%m-%d\"'
1637      Description: Date format.
1638
1639 `smarty-modify-date-prefix-string'
1640      Type: string
1641      Default value: `\"\"'
1642      Description: Prefix string of modification date in Smarty file
1643      header.
1644
1645 `smarty-modify-date-on-saving'
1646      Type: bool
1647      Default value: `nil'
1648      Description: If `t'; update the modification date when the
1649      buffer is saved.
1650
1651 3.1.5 Miscellaneous
1652 -------------------
1653
1654 `smarty-left-delimiter'
1655      Type: string
1656      Default value: `\"\"'
1657      Description: Left escaping delimiter for Smarty templates.
1658
1659 `smarty-right-delimiter'
1660      Type: string
1661      Default value: `\"\"'
1662      Description: Right escaping delimiter for Smarty templates.
1663
1664 `smarty-intelligent-tab'
1665      Type: bool
1666      Default value: `t'
1667      Description: If `t'; TAB does indentation; completion and insert
1668      tabulations. If `nil'; TAB does only indentation.
1669
1670 `smarty-word-completion-in-minibuffer'
1671      Type: bool
1672      Default value: `t'
1673      Description: If `t'; enable completion in the minibuffer.
1674
1675 `smarty-word-completion-case-sensitive'
1676      Type: bool
1677      Default value: `nil'
1678      Description: If `t'; completion is case sensitive.
1679
1680 3.2 Functions
1681 =============
1682
1683 3.2.1 Mode
1684 ----------
1685
1686 `smarty-electric-mode'
1687      Menu: Smarty -> Options -> Mode -> Electric Mode
1688      Keybinding: `C-c C-m C-e'
1689      Description: This functions is used to enable/disable the
1690      electric mode.
1691
1692 `smarty-stutter-mode'
1693      Menu: Smarty -> Options -> Mode -> Stutter Mode
1694      Keybinding: `C-c C-m C-s'
1695      Description: This function is used to enable/disable the stutter
1696      mode.
1697
1698 4 Menus
1699 *******
1700
1701 There are 2 menus: Smarty and Sources. All theses menus can be
1702 accessed from the menubar or from the right click. This chapter
1703 describes each menus.
1704
1705 4.1 Smarty
1706 ==========
1707
1708 This is the main menu of Smarty Mode. It allows an easy access to the
1709 main features of the Smarty Mode: Templates (see *Note Templates::)
1710 and Options (see *Note Customization::).
1711
1712 This menu contains also 3 functions that are discussed in the next
1713 part.
1714
1715 4.1.1 Functions
1716 ---------------
1717
1718 `smarty-show-messages'
1719      Menu: Smarty -> Show Messages
1720      Keybinding: `C-c M-m'
1721      Description: This function opens the *Messages* buffer to
1722      display previous error messages.
1723
1724 `smarty-doc-mode'
1725      Menu: Smarty -> Smarty Mode Documentation
1726      Keybinding: `C-c C-h'
1727      Description: This function opens the *Help* buffer and prints in
1728      it the Smarty Mode documentation.
1729
1730 `smarty-version'
1731      Menu: Smarty -> Version
1732      Keybinding: `C-c C-v'
1733      Description: This function displays in the minibuffer the
1734      current Smarty Mode version with the timestamp.
1735
1736 4.2 Sources
1737 ===========
1738
1739 The Sources menu shows the Smarty files in the current directory. If
1740 you add or delete a file in the current directory, you need to
1741 refresh the menu.
1742
1743 4.2.1 Customization
1744 -------------------
1745
1746 `smarty-source-file-menu'
1747      Type: boolean
1748      Default value: `t'
1749      Description: If `t'; the Sources menu is enabled. This menu
1750      contains the list of Smarty file located in the current
1751      directory. The Sources menu scans the directory when a file is
1752      opened.
1753
1754 4.2.2 Functions
1755 ---------------
1756
1757 `smarty-add-source-files-menu'
1758      Menu: Sources -> *Rescan*
1759      Keybinding: `C-c C-s C-u'
1760      Description: This function is used to refresh the Sources menu.
1761
1762 5 Stuttering
1763 ************
1764
1765 The stutter mode is a mode that affects a function to a key. For
1766 example, when you use the `ENTER' key, the associated function will
1767 create a new line and indent it.
1768
1769 5.1 Customization
1770 =================
1771
1772 `smarty-stutter-mode'
1773      Type: boolean
1774      Default value: `t'
1775      Description: If `t'; enable the stuttering. Is indicated in the
1776      modeline by \"/s\" after the mode name and can be toggled by
1777      `smarty-stutter-mode'.
1778
1779 5.2 Functions
1780 =============
1781
1782 `SPACE'
1783      If in comment, indent the comment and add new line if necessary.
1784      In other case, add a space.
1785
1786 `('
1787      If the previous character is a `(', the `((' will be replaced by
1788      `['.
1789      If the previous character is a `[', the `[(' will be replaced by
1790      `{'.
1791      In other case, insert a `('.
1792
1793 `)'
1794      If the previous character is a `)', the `))' will be replaced by
1795      `]'.
1796      If the previous character is a `]', the `])' will be replaced by
1797      `}'.
1798      In other case, insert a `)'.
1799
1800 6 Templates
1801 ***********
1802
1803 In the Smarty Mode, the Smarty functions (like if, while, for, fopen,
1804 fclose) are predefined in functions called \"Templates\".
1805
1806 Each template can be invoked by the function name or by using the
1807 <SPACE> key after the Smarty function name in the buffer (Note, using
1808 `M-<SPACE>' disable the template).
1809
1810 A template can be aborted by using the `C-g' or by lefting empty the
1811 tempate prompt (in the minibuffer).
1812
1813 6.1 Customization
1814 =================
1815
1816 `smarty-electric-mode'
1817      Type: boolean
1818      Default value: `t'
1819      Description: If `t'; enable automatic generation of template.
1820      If `nil'; template generators can still be invoked through key
1821      bindings and menu. Is indicated in the modeline by \"/e\" after
1822      the mode name and can be toggled by `smarty-electric-mode'.
1823
1824 For a complete description of the template customizable variables,
1825 see *Note Cu01-Pa01-Template::
1826
1827 6.2 Functions
1828 =============
1829
1830 6.2.1 Smarty Functions
1831 ----------------------
1832
1833 For Smarty functions, see PDF or HTML documentation.
1834
1835 6.2.2 Non-Smarty Functions
1836 --------------------------
1837
1838 `smarty-template-header'
1839      Menu: Smarty -> Templates -> Insert Header
1840      Keybinding: `C-c C-t C-h'
1841      Description: This function is used to insert a header in the
1842      current buffer.
1843
1844 `smarty-template-footer'
1845      Menu: Smarty -> Templates -> Insert Footer
1846      Keybinding: `C-c C-t C-f'
1847      Description: This function is used to insert a footer in the
1848      current buffer.
1849
1850 `smarty-template-insert-date'
1851      Menu: Smarty -> Templates -> Insert Date
1852      Keybinding: `C-c C-t C-d i'
1853      Description: This function is used to insert the date in the
1854      current buffer.
1855
1856 `smarty-template-modify'
1857      Menu: Smarty -> Templates -> Modify Date
1858      Keybinding: `C-c C-t C-d m'
1859      Description: This function is used to modify the last
1860      modification date in the current buffer.
1861
1862 7 Bugs, Help
1863 ************
1864
1865    * To report bugs: Bugtracker
1866      (http://bugtracker.morinie.fr/lisp/set_project.php?project_id=2)
1867
1868    * To obtain help you can post on the dedicated forum: Forum
1869      (http://forum.morinie.fr/lisp/)
1870
1871 8 Key bindings
1872 **************
1873
1874 \\{smarty-mode-map}"
1875   (interactive)
1876   (kill-all-local-variables)
1877   (setq major-mode 'smarty-mode)
1878   (setq mode-name "Smarty")
1879
1880   (smarty-create-syntax-table)
1881
1882   ;; set maps and tables
1883   (use-local-map smarty-mode-map)
1884   (set-syntax-table smarty-mode-syntax-table)
1885   (setq local-abbrev-table smarty-mode-abbrev-table)
1886
1887   (set (make-local-variable 'comment-start) (concat smarty-left-delimiter "*"))
1888   (set (make-local-variable 'comment-end) (concat "*" smarty-right-delimiter))
1889   (set (make-local-variable 'comment-multi-line) t)
1890   (set (make-local-variable 'smarty-end-comment-column) 80)
1891
1892   (make-local-variable 'font-lock-defaults)
1893   (if smarty-highlight-plugin-functions
1894       (setq smarty-font-lock-keywords smarty-font-lock-keywords-4)
1895     (setq smarty-font-lock-keywords smarty-font-lock-keywords-3))
1896   (setq font-lock-defaults
1897                 '((smarty-font-lock-keywords)
1898                 nil ; Keywords only (i.e. no comment or string highlighting
1899                 t   ; case fold
1900                 nil ; syntax-alist
1901                 nil ; syntax-begin
1902                 ))
1903
1904   (setq font-lock-maximum-decoration t
1905                 case-fold-search t)
1906
1907   ;; add source file menu
1908   (if smarty-source-file-menu (smarty-add-source-files-menu))
1909   ;; add Smarty menu
1910   (easy-menu-add smarty-mode-menu-list)
1911   (easy-menu-define smarty-mode-menu smarty-mode-map
1912                     "Menu keymap for Smarty Mode." smarty-mode-menu-list)
1913
1914   ;; (message "Smarty Mode %s.%s" smarty-version
1915   ;;          (if noninteractive "" "  See menu for documentation and release notes."))
1916   (smarty-mode-line-update)
1917   (run-hooks 'smarty-mode-hook))
1918
1919 (defun smarty-doc-mode ()
1920   "Display Smarty Mode documentation in *Help* buffer."
1921   (interactive)
1922   (with-output-to-temp-buffer
1923       (if (fboundp 'help-buffer) (help-buffer) "*Help*")
1924     (princ mode-name)
1925     (princ " mode:\n")
1926     (princ (documentation 'smarty-mode))
1927     (with-current-buffer standard-output
1928       (help-mode))
1929     (print-help-return-message)))
1930
1931 (defun smarty-activate-customizations ()
1932   "Activate all customizations on local variables."
1933   (interactive)
1934   (smarty-mode-map-init)
1935   (use-local-map smarty-mode-map)
1936   (set-syntax-table smarty-mode-syntax-table)
1937   (smarty-update-mode-menu)
1938   (run-hooks 'menu-bar-update-hook)
1939   (smarty-mode-line-update))
1940
1941 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1942 ;;; Templates
1943 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1944
1945 (defun smarty-template-field (prompt &optional follow-string optional
1946                                    begin end is-string string-char default)
1947   "Prompt for string and insert it in buffer with optional FOLLOW-STRING.
1948 If OPTIONAL is nil, the prompt is left if an empty string is inserted.  If
1949 an empty string is inserted, return nil and call `smarty-template-undo' for
1950 the region between BEGIN and END.  IS-STRING indicates whether a string
1951 with double-quotes is to be inserted.  DEFAULT specifies a default string."
1952   (let ((position (point))
1953         string)
1954     (insert "<" prompt ">")
1955     (if (not (> (length string-char) 0))
1956         (setq string-char "\""))
1957     (setq string
1958           (condition-case ()
1959               (read-from-minibuffer (concat prompt ": ")
1960                                     (or (and is-string (cons (concat string-char string-char) 1)) default)
1961                                     smarty-minibuffer-local-map)
1962             (quit (if (and optional begin end)
1963                       (progn (beep) "")
1964                     (keyboard-quit)))))
1965     (when (or (not (equal string "")) optional)
1966       (delete-region position (point)))
1967     (when (and (equal string "") optional begin end)
1968       (smarty-template-undo begin end)
1969       (message "Template aborted"))
1970     (unless (equal string "")
1971       (insert string))
1972     (when (or (not (equal string "")) (not optional))
1973       (insert (or follow-string "")))
1974     (if (equal string "") nil string)))
1975
1976 (defun smarty-template-undo (begin end)
1977   "Undo aborted template by deleting region and unexpanding the keyword."
1978   (cond (smarty-template-invoked-by-hook
1979          (goto-char end)
1980          (insert " ")
1981          (delete-region begin end)
1982          (unexpand-abbrev))
1983         (t (delete-region begin end))))
1984
1985 (defun smarty-template-generic-function (label close-label field mandatory-count &optional infinite special-field force-var)
1986   "Generic function template 'label field1= field2=..."
1987   (interactive)
1988   (let ((start (point)) found here result-value elt continue field-count stop prompt)
1989     (if smarty-template-invoked-by-hook
1990         (setq found (smarty-after-ldelim))
1991       (insert smarty-left-delimiter)
1992       (setq found t))
1993     (insert label)
1994     (setq here (point-marker))
1995     (insert " ")
1996     (when found
1997       (setq elt field)
1998       (setq continue t)
1999       (setq field-count 0)
2000       (setq stop nil)
2001       (while (and elt continue)
2002         (setq prompt (car elt))
2003         (when (not special-field)
2004           (insert prompt "="))
2005         (setq result-value (smarty-template-field prompt nil t))
2006         (if (and (not result-value)
2007                  (< field-count mandatory-count))
2008             (progn (setq continue nil)
2009                    (delete-region start (point))
2010                    (insert (concat label " "))
2011                    (setq stop t))
2012           (if (not result-value)
2013               (setq continue nil)
2014             (setq here (point-marker))
2015             (insert " ")))
2016         (setq field-count (+ 1 field-count))
2017         (setq elt (cdr elt)))
2018       (when (and infinite (or continue force-var))
2019         (when (not continue)
2020           (delete-region here (point))
2021           (insert " "))
2022         (setq continue t)
2023         (while continue
2024           (setq result-value (smarty-template-field "var_name" "=" t here))
2025           (if (not result-value)
2026               (setq continue nil)
2027             (setq continue (smarty-template-field "var_value" nil t here))
2028             (setq here (point-marker))
2029             (insert " "))))
2030       (when (not stop)
2031         (delete-region here (point))
2032         (if (> 0 mandatory-count)
2033             (delete-char -1))
2034         (insert smarty-right-delimiter)
2035         (setq here (point-marker))
2036         (if close-label
2037             (insert smarty-left-delimiter "/" label smarty-right-delimiter))
2038         (goto-char here)))))
2039
2040 (defun smarty-template-generic-modifier (label field mandatory-count)
2041   "Generic modifier template '|label:field1:field2..."
2042   (interactive)
2043   (let ((start (point)) found here result-value elt continue field-count stop prompt)
2044     (setq found (re-search-backward (concat (regexp-quote smarty-left-delimiter) "\\$\\(\\sw\\|\\s.\\)+" (regexp-quote "|")) nil t))
2045     (if found
2046         (progn
2047           (setq found (re-search-forward (regexp-quote smarty-right-delimiter) start t))
2048           (if (not found)
2049               (progn
2050                 (goto-char start)
2051                 (insert label)
2052                 (setq here (point-marker))
2053                 (setq elt field)
2054                 (setq continue t)
2055                 (setq field-count 0)
2056                 (setq stop nil)
2057                 (while (and elt continue)
2058                   (setq prompt (car elt))
2059                   (insert ":")
2060                   (setq result-value (smarty-template-field prompt nil t))
2061                   (if (and (not result-value)
2062                            (< field-count mandatory-count))
2063                       (progn (setq continue nil)
2064                              (delete-region start (point))
2065                              (insert (concat label " "))
2066                              (setq stop t))
2067                     (if (not result-value)
2068                         (setq continue nil)
2069                       (setq here (point-marker))
2070                       (insert ":")))
2071                   (setq field-count (+ 1 field-count))
2072                   (setq elt (cdr elt)))
2073                 (when (not stop)
2074                   (delete-region here (point))
2075                   (if (not (or (looking-at smarty-right-delimiter)
2076                                (looking-at "|")))
2077                       (insert smarty-right-delimiter))))
2078             (goto-char start)
2079             (insert label " ")))
2080       (goto-char start)
2081       (insert label " "))))
2082
2083 (defun smarty-template-capture-hook ()
2084   (smarty-hooked-abbrev 'smarty-template-capture))
2085 (defun smarty-template-config-load-hook ()
2086   (smarty-hooked-abbrev 'smarty-template-config-load))
2087 (defun smarty-template-else-hook ()
2088   (smarty-hooked-abbrev 'smarty-template-else))
2089 (defun smarty-template-elseif-hook ()
2090   (smarty-hooked-abbrev 'smarty-template-elseif))
2091 (defun smarty-template-foreach-hook ()
2092   (smarty-hooked-abbrev 'smarty-template-foreach))
2093 (defun smarty-template-foreachelse-hook ()
2094   (smarty-hooked-abbrev 'smarty-template-foreachelse))
2095 (defun smarty-template-if-hook ()
2096   (smarty-hooked-abbrev 'smarty-template-if))
2097 (defun smarty-template-include-hook ()
2098   (smarty-hooked-abbrev 'smarty-template-include))
2099 (defun smarty-template-include-php-hook ()
2100   (smarty-hooked-abbrev 'smarty-template-include-php))
2101 (defun smarty-template-insert-hook ()
2102   (smarty-hooked-abbrev 'smarty-template-insert))
2103 (defun smarty-template-ldelim-hook ()
2104   (smarty-hooked-abbrev 'smarty-template-ldelim))
2105 (defun smarty-template-literal-hook ()
2106   (smarty-hooked-abbrev 'smarty-template-literal))
2107 (defun smarty-template-php-hook ()
2108   (smarty-hooked-abbrev 'smarty-template-php))
2109 (defun smarty-template-rdelim-hook ()
2110   (smarty-hooked-abbrev 'smarty-template-rdelim))
2111 (defun smarty-template-section-hook ()
2112   (smarty-hooked-abbrev 'smarty-template-section))
2113 (defun smarty-template-sectionelse-hook ()
2114   (smarty-hooked-abbrev 'smarty-template-sectionelse))
2115 (defun smarty-template-strip-hook ()
2116   (smarty-hooked-abbrev 'smarty-template-strip))
2117
2118 (defun smarty-template-assign-hook ()
2119   (smarty-hooked-abbrev 'smarty-template-assign))
2120 (defun smarty-template-counter-hook ()
2121   (smarty-hooked-abbrev 'smarty-template-counter))
2122 (defun smarty-template-cycle-hook ()
2123   (smarty-hooked-abbrev 'smarty-template-cycle))
2124 (defun smarty-template-debug-hook ()
2125   (smarty-hooked-abbrev 'smarty-template-debug))
2126 (defun smarty-template-eval-hook ()
2127   (smarty-hooked-abbrev 'smarty-template-eval))
2128 (defun smarty-template-fetch-hook ()
2129   (smarty-hooked-abbrev 'smarty-template-fetch))
2130 (defun smarty-template-html-checkboxes-hook ()
2131   (smarty-hooked-abbrev 'smarty-template-html-checkboxes))
2132 (defun smarty-template-html-image-hook ()
2133   (smarty-hooked-abbrev 'smarty-template-html-image))
2134 (defun smarty-template-html-options-hook ()
2135   (smarty-hooked-abbrev 'smarty-template-html-options))
2136 (defun smarty-template-html-radios-hook ()
2137   (smarty-hooked-abbrev 'smarty-template-html-radios))
2138 (defun smarty-template-html-select-date-hook ()
2139   (smarty-hooked-abbrev 'smarty-template-html-select-date))
2140 (defun smarty-template-html-select-time-hook ()
2141   (smarty-hooked-abbrev 'smarty-template-html-select-time))
2142 (defun smarty-template-html-table-hook ()
2143   (smarty-hooked-abbrev 'smarty-template-html-table))
2144 (defun smarty-template-mailto-hook ()
2145   (smarty-hooked-abbrev 'smarty-template-mailto))
2146 (defun smarty-template-math-hook ()
2147   (smarty-hooked-abbrev 'smarty-template-math))
2148 (defun smarty-template-popup-hook ()
2149   (smarty-hooked-abbrev 'smarty-template-popup))
2150 (defun smarty-template-popup-init-hook ()
2151   (smarty-hooked-abbrev 'smarty-template-popup-init))
2152 (defun smarty-template-textformat-hook ()
2153   (smarty-hooked-abbrev 'smarty-template-textformat))
2154
2155 (defun smarty-template-capitalize-hook ()
2156   (smarty-hooked-abbrev 'smarty-template-capitalize))
2157 (defun smarty-template-cat-hook ()
2158   (smarty-hooked-abbrev 'smarty-template-cat))
2159 (defun smarty-template-count-characters-hook ()
2160   (smarty-hooked-abbrev 'smarty-template-count-characters))
2161 (defun smarty-template-count-paragraphs-hook ()
2162   (smarty-hooked-abbrev 'smarty-template-count-paragraphs))
2163 (defun smarty-template-count-sentences-hook ()
2164   (smarty-hooked-abbrev 'smarty-template-count-sentences))
2165 (defun smarty-template-count-words-hook ()
2166   (smarty-hooked-abbrev 'smarty-template-count-words))
2167 (defun smarty-template-date-format-hook ()
2168   (smarty-hooked-abbrev 'smarty-template-date-format))
2169 (defun smarty-template-default-hook ()
2170   (smarty-hooked-abbrev 'smarty-template-default))
2171 (defun smarty-template-escape-hook ()
2172   (smarty-hooked-abbrev 'smarty-template-escape))
2173 (defun smarty-template-indent-hook ()
2174   (smarty-hooked-abbrev 'smarty-template-indent))
2175 (defun smarty-template-lower-hook ()
2176   (smarty-hooked-abbrev 'smarty-template-lower))
2177 (defun smarty-template-nl2br-hook ()
2178   (smarty-hooked-abbrev 'smarty-template-nl2br))
2179 (defun smarty-template-regex-replace-hook ()
2180   (smarty-hooked-abbrev 'smarty-template-regex-replace))
2181 (defun smarty-template-replace-hook ()
2182   (smarty-hooked-abbrev 'smarty-template-replace))
2183 (defun smarty-template-spacify-hook ()
2184   (smarty-hooked-abbrev 'smarty-template-spacify))
2185 (defun smarty-template-string-format-hook ()
2186   (smarty-hooked-abbrev 'smarty-template-string-format))
2187 (defun smarty-template-vstrip-hook ()
2188   (smarty-hooked-abbrev 'smarty-template-vstrip))
2189 (defun smarty-template-strip-tags-hook ()
2190   (smarty-hooked-abbrev 'smarty-template-strip-tags))
2191 (defun smarty-template-truncate-hook ()
2192   (smarty-hooked-abbrev 'smarty-template-truncate))
2193 (defun smarty-template-upper-hook ()
2194   (smarty-hooked-abbrev 'smarty-template-upper))
2195 (defun smarty-template-wordwrap-hook ()
2196   (smarty-hooked-abbrev 'smarty-template-wordwrap))
2197
2198 (defun smarty-template-validate-hook ()
2199   (smarty-hooked-abbrev 'smarty-template-validate))
2200 (defun smarty-template-clipcache-hook ()
2201   (smarty-hooked-abbrev 'smarty-template-clipcache))
2202 (defun smarty-template-include-clipcache-hook ()
2203   (smarty-hooked-abbrev 'smarty-template-include-clipcache))
2204 (defun smarty-template-formtool-checkall-hook ()
2205   (smarty-hooked-abbrev 'smarty-template-formtool-checkall))
2206 (defun smarty-template-formtool-copy-hook ()
2207   (smarty-hooked-abbrev 'smarty-template-formtool-copy))
2208 (defun smarty-template-formtool-count-chars-hook ()
2209   (smarty-hooked-abbrev 'smarty-template-formtool-count-chars))
2210 (defun smarty-template-formtool-init-hook ()
2211   (smarty-hooked-abbrev 'smarty-template-formtool-init))
2212 (defun smarty-template-formtool-move-hook ()
2213   (smarty-hooked-abbrev 'smarty-template-formtool-move))
2214 (defun smarty-template-formtool-moveall-hook ()
2215   (smarty-hooked-abbrev 'smarty-template-formtool-moveall))
2216 (defun smarty-template-formtool-movedown-hook ()
2217   (smarty-hooked-abbrev 'smarty-template-formtool-movedown))
2218 (defun smarty-template-formtool-moveup-hook ()
2219   (smarty-hooked-abbrev 'smarty-template-formtool-moveup))
2220 (defun smarty-template-formtool-remove-hook ()
2221   (smarty-hooked-abbrev 'smarty-template-formtool-remove))
2222 (defun smarty-template-formtool-rename-hook ()
2223   (smarty-hooked-abbrev 'smarty-template-formtool-rename))
2224 (defun smarty-template-formtool-save-hook ()
2225   (smarty-hooked-abbrev 'smarty-template-formtool-save))
2226 (defun smarty-template-formtool-selectall-hook ()
2227   (smarty-hooked-abbrev 'smarty-template-formtool-selectall))
2228 (defun smarty-template-paginate-first-hook ()
2229   (smarty-hooked-abbrev 'smarty-template-paginate-first))
2230 (defun smarty-template-paginate-last-hook ()
2231   (smarty-hooked-abbrev 'smarty-template-paginate-last))
2232 (defun smarty-template-paginate-middle-hook ()
2233   (smarty-hooked-abbrev 'smarty-template-paginate-middle))
2234 (defun smarty-template-paginate-next-hook ()
2235   (smarty-hooked-abbrev 'smarty-template-paginate-next))
2236 (defun smarty-template-paginate-prev-hook ()
2237   (smarty-hooked-abbrev 'smarty-template-paginate-prev))
2238
2239 (defun smarty-template-btosmilies-hook ()
2240   (smarty-hooked-abbrev 'smarty-template-btosmilies))
2241 (defun smarty-template-bbcodetohtml-hook ()
2242   (smarty-hooked-abbrev 'smarty-template-bbcodetohtml))
2243 (defun smarty-template-date-formatto-hook ()
2244   (smarty-hooked-abbrev 'smarty-template-date-formatto))
2245
2246 (defun smarty-template-capture ()
2247   "Insert a capture statement."
2248   (interactive)
2249   (smarty-template-generic-function "capture" t '("name" "assign") 0))
2250
2251 (defun smarty-template-config-load ()
2252   "Insert a config_load statement."
2253   (interactive)
2254   (smarty-template-generic-function "config_load" nil '("file" "section" "scope" "global") 1))
2255
2256 (defun smarty-template-else ()
2257   "Insert a else statement."
2258   (interactive)
2259   (smarty-template-generic-function "else" nil '() 0))
2260
2261 (defun smarty-template-elseif ()
2262   "Insert a elseif statement."
2263   (interactive)
2264   (smarty-template-generic-function "elseif" nil '("condition") 1 nil t))
2265
2266 (defun smarty-template-foreach ()
2267   "Insert a foreach statement."
2268   (interactive)
2269   (smarty-template-generic-function "foreach" t '("from" "item" "key" "name") 2))
2270
2271 (defun smarty-template-foreachelse ()
2272   "Insert a foreachelse statement."
2273   (interactive)
2274   (smarty-template-generic-function "foreachelse" nil '() 0))
2275
2276 (defun smarty-template-if ()
2277   "Insert a if statement."
2278   (interactive)
2279   (smarty-template-generic-function "if" t '("condition") 1 nil t))
2280
2281 (defun smarty-template-include ()
2282   "Insert a include statement."
2283   (interactive)
2284   (smarty-template-generic-function "include" nil '("file" "assign") 1 t))
2285
2286 (defun smarty-template-include-php ()
2287   "Insert a include_php statement."
2288   (interactive)
2289   (smarty-template-generic-function "include_php" nil '("file" "once" "assign") 1))
2290
2291 (defun smarty-template-insert ()
2292   "Insert a insert statement."
2293   (interactive)
2294   (smarty-template-generic-function "insert" nil '("name" "assign" "script") 1 t))
2295
2296 (defun smarty-template-ldelim ()
2297   "Insert a ldelim statement."
2298   (interactive)
2299   (smarty-template-generic-function "ldelim" nil '() 0))
2300
2301 (defun smarty-template-literal ()
2302   "Insert a literal statement."
2303   (interactive)
2304   (smarty-template-generic-function "literal" t '() 0))
2305
2306 (defun smarty-template-php ()
2307   "Insert a php statement."
2308   (interactive)
2309   (smarty-template-generic-function "php" t '() 0))
2310
2311 (defun smarty-template-rdelim ()
2312   "Insert a rdelim statement."
2313   (interactive)
2314   (smarty-template-generic-function "rdelim" nil '() 0))
2315
2316 (defun smarty-template-section ()
2317   "Insert a section statement."
2318   (interactive)
2319   (smarty-template-generic-function "section" t '("name" "loop" "start" "step" "max" "show") 2))
2320
2321 (defun smarty-template-sectionelse ()
2322   "Insert a sectionelse statement."
2323   (interactive)
2324   (smarty-template-generic-function "sectionelse" nil '() 0))
2325
2326 (defun smarty-template-strip ()
2327   "Insert a strip statement."
2328   (interactive)
2329   (smarty-template-generic-function "strip" t '() 0))
2330
2331
2332 (defun smarty-template-assign ()
2333   "Insert a assign statement."
2334   (interactive)
2335   (smarty-template-generic-function "assign" nil '("var" "value") 2))
2336
2337 (defun smarty-template-counter ()
2338   "Insert a counter statement."
2339   (interactive)
2340   (smarty-template-generic-function "counter" nil '("name" "start" "skip" "direction" "print" "assign") 0))
2341
2342 (defun smarty-template-cycle ()
2343   "Insert a cycle statement."
2344   (interactive)
2345   (smarty-template-generic-function "cycle" nil '("values" "name" "print" "advance" "delimiter" "assign" "reset") 1))
2346
2347 (defun smarty-template-debug ()
2348   "Insert a debug statement."
2349   (interactive)
2350   (smarty-template-generic-function "debug" nil '("output") 0))
2351
2352 (defun smarty-template-eval ()
2353   "Insert a eval statement."
2354   (interactive)
2355   (smarty-template-generic-function "eval" nil '("var" "assign") 1))
2356
2357 (defun smarty-template-fetch ()
2358   "Insert a fetch statement."
2359   (interactive)
2360   (smarty-template-generic-function "fetch" nil '("file" "assign") 1))
2361
2362 (defun smarty-template-html-checkboxes ()
2363   "Insert a html_checkboxes statement."
2364   (interactive)
2365   (smarty-template-generic-function "html_checkboxes" nil '("name" "values" "output" "selected" "options" "separator" "assign" "labels") 0))
2366
2367 (defun smarty-template-html-image ()
2368   "Insert a html_image statement."
2369   (interactive)
2370   (smarty-template-generic-function "html_image" nil '("file" "height" "width" "basedir" "alt" "href" "path_prefix") 1))
2371
2372 (defun smarty-template-html-options ()
2373   "Insert a html_options statement."
2374   (interactive)
2375   (smarty-template-generic-function "html_options" nil '("name" "values" "output" "selected" "options") 0))
2376
2377 (defun smarty-template-html-radios ()
2378   "Insert a html_radios statement."
2379   (interactive)
2380   (smarty-template-generic-function "html_radios" nil '("name" "values" "output" "selected" "options" "separator" "assign") 0))
2381
2382 (defun smarty-template-html-select-date ()
2383   "Insert a html_select_date statement."
2384   (interactive)
2385   (smarty-template-generic-function "html_select_date" nil '("prefix" "time" "start_year" "end_year" "display_days" "display_months" "display_years" "month_format" "day_format" "day_value_format" "year_as_text" "reverse_years" "field_array" "day_size" "month_size" "year_size" "all_extra" "day_extra" "month_extra" "year_extra" "field_order" "field_separator" "month_value_format" "year_empty" "month_empty" "day_empty") 0))
2386
2387 (defun smarty-template-html-select-time ()
2388   "Insert a html_select_time statement."
2389   (interactive)
2390   (smarty-template-generic-function "html_select_time" nil '("prefix" "time" "display_hours" "display_minutes" "display_seconds" "display_meridian" "use_24_hours" "minute_interval" "second_interval" "field_array" "all_extra" "hour_extra" "minute_extra" "second_extra" "meridian_extra") 0))
2391
2392 (defun smarty-template-html-table ()
2393   "Insert a html_table statement."
2394   (interactive)
2395   (smarty-template-generic-function "html_table" nil '("loop" "cols" "rows" "inner" "caption" "table_attr" "th_attr" "tr_attr" "td_attr" "trailpad" "hdir" "vdir") 1))
2396
2397 (defun smarty-template-mailto ()
2398   "Insert a mailto statement."
2399   (interactive)
2400   (smarty-template-generic-function "mailto" nil '("address" "text" "encode" "cc" "bcc" "subject" "newsgroups" "followupto" "extra") 1))
2401
2402 (defun smarty-template-math ()
2403   "Insert a math statement."
2404   (interactive)
2405   (smarty-template-generic-function "math" nil '("equation" "format" "assign") 1 t nil t))
2406
2407 (defun smarty-template-popup ()
2408   "Insert a popup statement."
2409   (interactive)
2410   (smarty-template-generic-function "popup" nil '("text" "trigger" "sticky" "caption" "fgcolor" "bgcolor" "textcolor" "capcolor" "closecolor" "textfont" "captionfont" "closefont" "textsize" "captionsize" "closesize" "width" "height" "left" "right" "center" "above" "below" "border" "offsetx" "offsety" "fgbackground" "bgbackground" "closetext" "noclose" "status" "autostatus" "autostatuscap" "inarray" "caparray" "capicon" "snapx" "snapy" "fixx" "fixy" "background" "padx" "pady" "fullhtml" "frame" "function" "delay" "hauto" "vauto") 1))
2411
2412 (defun smarty-template-popup-init ()
2413   "Insert a popup_init statement."
2414   (interactive)
2415   (smarty-template-generic-function "popup_init" nil '("src") 1))
2416
2417 (defun smarty-template-textformat ()
2418   "Insert a textformat statement."
2419   (interactive)
2420   (smarty-template-generic-function "textformat" t '("style" "indent" "indent_first" "indent_char" "wrap" "wrap_char" "wrap_cut" "assign") 0))
2421
2422 (defun smarty-template-capitalize ()
2423   "Insert a capitalize statement."
2424   (interactive)
2425   (smarty-template-generic-modifier "capitalize" '("upcase_numeric") 0))
2426
2427 (defun smarty-template-cat ()
2428   "Insert a cat statement."
2429   (interactive)
2430   (smarty-template-generic-modifier "cat" '("value") 0))
2431
2432 (defun smarty-template-count-characters ()
2433   "Insert a count_characters statement."
2434   (interactive)
2435   (smarty-template-generic-modifier "count_characters" '("include_whitespace") 0))
2436
2437 (defun smarty-template-count-paragraphs ()
2438   "Insert a count_paragraphs statement."
2439   (interactive)
2440   (smarty-template-generic-modifier "count_paragraphs" '() 0))
2441
2442 (defun smarty-template-count-sentences ()
2443   "Insert a count_sentences statement."
2444   (interactive)
2445   (smarty-template-generic-modifier "count_sentences" '() 0))
2446
2447 (defun smarty-template-count-words ()
2448   "Insert a count_words statement."
2449   (interactive)
2450   (smarty-template-generic-modifier "count_words" '() 0))
2451
2452 (defun smarty-template-date-format ()
2453   "Insert a date_format statement."
2454   (interactive)
2455   (smarty-template-generic-modifier "date_format" '("format" "default") 0))
2456
2457 (defun smarty-template-default ()
2458   "Insert a default statement."
2459   (interactive)
2460   (smarty-template-generic-modifier "default" '("value") 0))
2461
2462 (defun smarty-template-escape ()
2463   "Insert a escape statement."
2464   (interactive)
2465   (smarty-template-generic-modifier "escape" '("html|htmlall|url|urlpathinfo|quotes|hex|hexentity|javascript|mail" "charset") 0))
2466
2467 (defun smarty-template-indent ()
2468   "Insert a indent statement."
2469   (interactive)
2470   (smarty-template-generic-modifier "indent" '("value" "character") 0))
2471
2472 (defun smarty-template-lower ()
2473   "Insert a lower statement."
2474   (interactive)
2475   (smarty-template-generic-modifier "lower" '() 0))
2476
2477 (defun smarty-template-nl2br ()
2478   "Insert a nl2br statement."
2479   (interactive)
2480   (smarty-template-generic-modifier "nl2br" '() 0))
2481
2482 (defun smarty-template-regex-replace ()
2483   "Insert a regex_replace statement."
2484   (interactive)
2485   (smarty-template-generic-modifier "regex_replace" '("regexp" "string_to_replace") 2))
2486
2487 (defun smarty-template-replace ()
2488   "Insert a replace statement."
2489   (interactive)
2490   (smarty-template-generic-modifier "replace" '("string" "string_to_replace_with") 2))
2491
2492 (defun smarty-template-spacify ()
2493   "Insert a spacify statement."
2494   (interactive)
2495   (smarty-template-generic-modifier "spacify" '("character") 0))
2496
2497 (defun smarty-template-string-format ()
2498   "Insert a string_format statement."
2499   (interactive)
2500   (smarty-template-generic-modifier "string_format" '("format") 1))
2501
2502 (defun smarty-template-vstrip ()
2503   "Insert a strip statement."
2504   (interactive)
2505   (smarty-template-generic-modifier "strip" '() 0))
2506
2507 (defun smarty-template-strip-tags ()
2508   "Insert a strip_tags statement."
2509   (interactive)
2510   (smarty-template-generic-modifier "strip_tags" '("replace_by_space") 0))
2511
2512 (defun smarty-template-truncate ()
2513   "Insert a truncate statement."
2514   (interactive)
2515   (smarty-template-generic-modifier "truncate" '("count" "text_to_replace" "character_boundary" "middle_string") 0))
2516
2517 (defun smarty-template-upper ()
2518   "Insert a upper statement."
2519   (interactive)
2520   (smarty-template-generic-modifier "upper" '() 0))
2521
2522 (defun smarty-template-wordwrap ()
2523   "Insert a wordwrap statement."
2524   (interactive)
2525   (smarty-template-generic-modifier "wordwrap" '("count" "string" "character_boundary") 0))
2526
2527
2528 (defun smarty-template-validate ()
2529   "Insert a validate statement."
2530   (interactive)
2531   (smarty-template-generic-function "validate" nil '("field" "criteria" "message" "form" "transform" "trim" "empty" "halt" "assign" "append" "page") 3))
2532
2533 (defun smarty-template-repeat ()
2534   "Insert a repeat statement."
2535   (interactive)
2536   (smarty-template-generic-function "repeat" nil '("count" "assign") 1))
2537
2538 (defun smarty-template-str_repeat ()
2539   "Insert a str_repeat statement."
2540   (interactive)
2541   (smarty-template-generic-function "str_repeat" nil '("string" "count" "assign") 2))
2542
2543 (defun smarty-template-clipcache ()
2544   "Insert a clipcache statement."
2545   (interactive)
2546   (smarty-template-generic-function "clipcache" nil '("id" "group" "ttl" "ldelim" "rdelim") 3))
2547
2548 (defun smarty-template-include-clipcache ()
2549   "Insert a include_clipcache statement."
2550   (interactive)
2551   (smarty-template-generic-function "include_clipcache" nil '("file" "cache_id" "cache_lifetime" "ldelim" "rdelim") 3))
2552
2553 (defun smarty-template-formtool-checkall ()
2554   "Insert a formtool_checkall statement."
2555   (interactive)
2556   (smarty-template-generic-function "formtool_checkall" nil '("name" "class" "style") 1))
2557
2558 (defun smarty-template-formtool-copy ()
2559   "Insert a formtool_copy statement."
2560   (interactive)
2561   (smarty-template-generic-function "formtool_copy" nil '("from" "to" "save" "button_text" "all" "counter" "class" "style") 3))
2562
2563 (defun smarty-template-formtool-count-chars ()
2564   "Insert a formtool_count_chars statement."
2565   (interactive)
2566   (smarty-template-generic-function "formtool_count_chars" nil '("name" "limit" "alert") 3))
2567
2568 (defun smarty-template-formtool-init ()
2569   "Insert a formtool_init statement."
2570   (interactive)
2571   (smarty-template-generic-function "formtool_init" nil '("src") 1))
2572
2573 (defun smarty-template-formtool-move ()
2574   "Insert a formtool_move statement."
2575   (interactive)
2576   (smarty-template-generic-function "formtool_move" nil '("from" "to" "save_from" "save_to" "all" "count_to" "count_from" "class" "style") 4))
2577
2578 (defun smarty-template-formtool-moveall ()
2579   "Insert a formtool_moveall statement."
2580   (interactive)
2581   (smarty-template-generic-function "formtool_moveall" nil '("from" "to" "save_from" "save_to" "all" "count_to" "count_from" "class" "style") 4))
2582
2583 (defun smarty-template-formtool-movedown ()
2584   "Insert a formtool_movedown statement."
2585   (interactive)
2586   (smarty-template-generic-function "formtool_movedown" nil '("save" "name" "class" "style") 2))
2587
2588 (defun smarty-template-formtool-moveup ()
2589   "Insert a formtool_moveup statement."
2590   (interactive)
2591   (smarty-template-generic-function "formtool_moveup" nil '("save" "name" "class" "style") 2))
2592
2593 (defun smarty-template-formtool-remove ()
2594   "Insert a formtool_remove statement."
2595   (interactive)
2596   (smarty-template-generic-function "formtool_remove" nil '("from" "save" "all" "counter" "class" "style") 2))
2597
2598 (defun smarty-template-formtool-rename ()
2599   "Insert a formtool_rename statement."
2600   (interactive)
2601   (smarty-template-generic-function "formtool_rename" nil '("name" "from" "save" "class" "style") 3))
2602
2603 (defun smarty-template-formtool-save ()
2604   "Insert a formtool_save statement."
2605   (interactive)
2606   (smarty-template-generic-function "formtool_save" nil '("from" "name" "save") 3))
2607
2608 (defun smarty-template-formtool-selectall ()
2609   "Insert a formtool_selectall statement."
2610   (interactive)
2611   (smarty-template-generic-function "formtool_selectall" nil '("name" "class" "style") 1))
2612
2613 (defun smarty-template-paginate-first ()
2614   "Insert a paginate_first statement."
2615   (interactive)
2616   (smarty-template-generic-function "paginate_first" nil '("id" "text") 0))
2617
2618 (defun smarty-template-paginate-last ()
2619   "Insert a paginate_last statement."
2620   (interactive)
2621   (smarty-template-generic-function "paginate_last" nil '("id" "text") 0))
2622
2623 (defun smarty-template-paginate-middle ()
2624   "Insert a paginate_middle statement."
2625   (interactive)
2626   (smarty-template-generic-function "paginate_middle" nil '("id" "format" "prefix" "page_limit" "link_prefix" "link_suffix") 0))
2627
2628 (defun smarty-template-paginate-next ()
2629   "Insert a paginate_next statement."
2630   (interactive)
2631   (smarty-template-generic-function "paginate_next" nil '("id" "text") 0))
2632
2633 (defun smarty-template-paginate-prev ()
2634   "Insert a paginate_prev statement."
2635   (interactive)
2636   (smarty-template-generic-function "paginate_prev" nil '("id" "text") 0))
2637
2638
2639 (defun smarty-template-btosmilies ()
2640   "Insert a B2Smilies statement."
2641   (interactive)
2642   (smarty-template-generic-modifier "B2Smilies" '() 0))
2643
2644 (defun smarty-template-bbcodetohtml ()
2645   "Insert a bbcode2html statement."
2646   (interactive)
2647   (smarty-template-generic-modifier "bbcode2html" '() 0))
2648
2649 (defun smarty-template-date-formatto ()
2650   "Insert a date_format2 statement."
2651   (interactive)
2652   (smarty-template-generic-modifier "date_format2" '("format" "default") 0))
2653
2654 ;;
2655
2656 (defun smarty-resolve-env-variable (string)
2657   "Resolve environment variables in STRING."
2658   (while (string-match "\\(.*\\)${?\\(\\(\\w\\|_\\)+\\)}?\\(.*\\)" string)
2659     (setq string (concat (match-string 1 string)
2660                          (getenv (match-string 2 string))
2661                          (match-string 4 string))))
2662   string)
2663
2664 (defun smarty-insert-string-or-file (string)
2665   "Insert STRING or file contents if STRING is an existing file name."
2666   (unless (equal string "")
2667     (let ((file-name
2668            (progn (string-match "^\\([^\n]+\\)" string)
2669                   (smarty-resolve-env-variable (match-string 1 string)))))
2670       (if (file-exists-p file-name)
2671            (forward-char (cadr (insert-file-contents file-name)))
2672         (insert string)))))
2673
2674 (defun smarty-template-insert-date ()
2675   "Insert date in appropriate format."
2676   (interactive)
2677   (insert
2678    (cond
2679     ;; 'american, 'european, 'scientific kept for backward compatibility
2680     ((eq smarty-date-format 'american) (format-time-string "%m/%d/%Y" nil))
2681     ((eq smarty-date-format 'european) (format-time-string "%d.%m.%Y" nil))
2682     ((eq smarty-date-format 'scientific) (format-time-string "%Y/%m/%d" nil))
2683     (t (format-time-string smarty-date-format nil)))))
2684
2685 (defun smarty-template-header (&optional file-title)
2686   "Insert a Smarty file header."
2687   (interactive)
2688   (unless (equal smarty-file-header "")
2689     (let (pos)
2690       (save-excursion
2691         (smarty-insert-string-or-file smarty-file-header)
2692         (setq pos (point-marker)))
2693       (smarty-template-replace-header-keywords
2694        (point-min-marker) pos file-title))))
2695
2696 (defun smarty-template-footer ()
2697   "Insert a Smarty file footer."
2698   (interactive)
2699   (unless (equal smarty-file-footer "")
2700     (let (pos)
2701       (save-excursion
2702         (setq pos (point-marker))
2703         (smarty-insert-string-or-file smarty-file-footer)
2704         (unless (= (preceding-char) ?\n)
2705           (insert "\n")))
2706       (smarty-template-replace-header-keywords pos (point-max-marker)))))
2707
2708 (defun smarty-template-replace-header-keywords (beg end &optional file-title is-model)
2709   "Replace keywords in header and footer."
2710   (let ()
2711     (smarty-prepare-search-2
2712      (save-excursion
2713        (goto-char beg)
2714        (while (search-forward "<filename>" end t)
2715          (replace-match (buffer-name) t t))
2716        (goto-char beg)
2717        (while (search-forward "<copyright>" end t)
2718          (replace-match smarty-copyright-string t t))
2719        (goto-char beg)
2720        (while (search-forward "<author>" end t)
2721          (replace-match "" t t)
2722          (insert (user-full-name))
2723          (when user-mail-address (insert "  <" user-mail-address ">")))
2724        (goto-char beg)
2725        (while (search-forward "<login>" end t)
2726          (replace-match (user-login-name) t t))
2727        (goto-char beg)
2728        (while (search-forward "<company>" end t)
2729          (replace-match smarty-company-name t t))
2730        (goto-char beg)
2731        ;; Replace <RCS> with $, so that RCS for the source is
2732        ;; not over-enthusiastic with replacements
2733        (while (search-forward "<RCS>" end t)
2734          (replace-match "$" nil t))
2735        (goto-char beg)
2736        (while (search-forward "<date>" end t)
2737          (replace-match "" t t)
2738          (smarty-template-insert-date))
2739        (goto-char beg)
2740        (while (search-forward "<year>" end t)
2741          (replace-match (format-time-string "%Y" nil) t t))
2742        (goto-char beg)
2743        (let (string)
2744          (while
2745              (re-search-forward "<\\(\\(\\w\\|\\s_\\)*\\) string>" end t)
2746            (setq string (read-string (concat (match-string 1) ": ")))
2747            (replace-match string t t)))
2748        (goto-char beg)
2749        (when (and (not is-model) (search-forward "<cursor>" end t))
2750          (replace-match "" t t))))))
2751
2752 (provide 'smarty-mode)
2753 ;;; smarty-mode.el ends here