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