diff --git a/.gitattributes b/.gitattributes
index 554c09cb5f00f70eb0cde415b7971dcf3480f0e0..b449bb68bf8da13586679efff1ce32a1deaf23c2 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -5846,6 +5846,9 @@ scripts/emacs/phpunit.el -text
 scripts/emacs/popup-0.5/popup-autoloads.el -text
 scripts/emacs/popup-0.5/popup-pkg.el -text
 scripts/emacs/popup-0.5/popup.el -text
+scripts/emacs/web-mode-master/README.md -text
+scripts/emacs/web-mode-master/web-mode.el -text
+scripts/emacs/web-mode-master/wfs-mode.el -text
 scripts/find_tests.php -text
 scripts/import_avis_csv.php -text
 scripts/import_sitotheque.php -text
diff --git a/scripts/emacs/phafi-autoload.el b/scripts/emacs/phafi-autoload.el
index fe761157ab1478f9082548481d21a415b6dd5225..6ce5e9728cfb7b041d8c9764d9d1a50bfb171314 100644
--- a/scripts/emacs/phafi-autoload.el
+++ b/scripts/emacs/phafi-autoload.el
@@ -35,18 +35,25 @@
 (phafi-autoload-load "nxhtml-2.08-100425")
 (phafi-autoload-load "popup-0.5")
 (phafi-autoload-load "auto-complete-1.4")
+(phafi-autoload-load "web-mode-master")
 
 (require 'php-mode)
 (add-to-list 'auto-mode-alist  '("\\.php[34]?\\'\\|\\.phtml\\'" . php-mode))
 
+
 (require 'magit)
 (require 'magit-svn)
 (add-hook 'magit-mode-hook 'turn-on-magit-svn)
 
 
-;; (load "nxhtml-2.08-100425/autostart.el")
-;; (add-to-list 'auto-mode-alist  '("\\.phtml\\'" . nxhtml-mumamo-mode))
-;; (require 'nxhtml-autostart)
+(require 'js)
+(defun phafi-js-mode()
+	(setq js-indent-level 2)
+	)
+(add-hook 'js-mode-hook 'phafi-js-mode)
+
+
+
 (require 'phafi-mode)
 
 (defun phafi-autoload-php-mode()
@@ -55,5 +62,18 @@
 
 (add-hook 'php-mode-hook 'phafi-autoload-php-mode t)
 
+
+
+(require 'web-mode) 
+(add-to-list 'auto-mode-alist '("\\.phtml\\'" . web-mode))
+(setq web-mode-engines-alist '(("php" . "\\.phtml\\'")) )
+
+(defun phafi-web-mode-hook () 
+	"Hooks for Web mode." 
+	(setq web-mode-markup-indent-offset 2)
+	(phafi-mode))
+(add-hook 'web-mode-hook 'phafi-web-mode-hook)
+
+
 (unless (featurep 'phafi-autoload)
   (provide 'phafi-autoload))
diff --git a/scripts/emacs/web-mode-master/README.md b/scripts/emacs/web-mode-master/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..0cef679166596c1de194c6b85a1db391cecb80a8
--- /dev/null
+++ b/scripts/emacs/web-mode-master/README.md
@@ -0,0 +1,10 @@
+web-mode.el  [![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/thing/1849746/web-mode-el)
+=========
+
+web-mode.el is an emacs major mode for editing **web templates** aka HTML files embedding client parts (CSS/JavaScript) and server blocks.
+
+web-mode.el is compatible with many template engines: PHP, JSP, ASP, Django, Twig, Jinja(2), ERB, FreeMarker, Velocity, Cheetah, Smarty, CTemplate, Mustache, Blade, ErlyDTL, Go Template, Dust.js, Google Closure (soy),  etc.
+
+More infos on http://web-mode.org/
+
+![ScreenShot](http://web-mode.org/web-mode.png?v=1)
diff --git a/scripts/emacs/web-mode-master/web-mode.el b/scripts/emacs/web-mode-master/web-mode.el
new file mode 100644
index 0000000000000000000000000000000000000000..340b58a21bcbcfd81f7ac3ed1b142a8c5a92226e
--- /dev/null
+++ b/scripts/emacs/web-mode-master/web-mode.el
@@ -0,0 +1,7063 @@
+;;; web-mode.el --- major mode for editing html templates -*- coding: utf-8 -*-
+
+;; Copyright 2011-2013 François-Xavier Bois
+
+;; Version: 7.0.22
+;; Author: François-Xavier Bois <fxbois AT Google Mail Service>
+;; Maintainer: François-Xavier Bois
+;; Created: July 2011
+;; Keywords: html template php javascript js css web
+;;           django jsp asp erb twig jinja blade dust closure
+;;           freemarker mustache velocity cheetah smarty
+;; URL: http://web-mode.org
+;; Repository: http://github.com/fxbois/web-mode
+
+;; =========================================================================
+;; This work is sponsored by Kernix : Digital Agency (Web & Mobile) in Paris
+;; =========================================================================
+
+;; This file is not part of Emacs
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;; Code goes here
+
+;;todo : auto-pairs deviennent spécifiques à un engine
+;;todo : reduction des css rules div { ... }
+;;todo : passer les content-types en symboles
+;;todo : tester shortcut A -> pour pomme
+;;todo : commentaire d'une ligne ruby ou d'une ligne asp
+;;todo : ne mettre tag-type et tag-name que sur le '<'
+;;todo : créer tag-token pour différentier de part-token : tag-token=attr,comment ???
+
+(defgroup web-mode nil
+  "Major mode for editing web templates:
+   HTML files embedding parts (CSS/JavaScript)
+   and blocks (PHP, Erb, Django/Twig, Smarty, JSP, ASP, etc.)."
+  :version "7.0.22"
+  :group 'languages)
+
+(defgroup web-mode-faces nil
+  "Faces for syntax highlighting."
+  :group 'web-mode
+  :group 'faces)
+
+(defcustom web-mode-script-padding 1
+  "Script element left padding."
+  :type 'integer
+  :group 'web-mode)
+
+(defcustom web-mode-style-padding 1
+  "Style element left padding."
+  :type 'integer
+  :group 'web-mode)
+
+(defcustom web-mode-block-padding 0
+  "Multi-line block (PHP, Ruby, Java, etc.) left padding."
+  :type 'integer
+  :group 'web-mode)
+
+(defcustom web-mode-markup-indent-offset 2
+  "HTML indentation level."
+  :type 'integer
+  :group 'web-mode)
+
+(defcustom web-mode-css-indent-offset 2
+  "CSS indentation level."
+  :type 'integer
+  :group 'web-mode)
+
+(defcustom web-mode-code-indent-offset 2
+  "Code (JavaScript, PHP, etc.) indentation level."
+  :type 'integer
+  :group 'web-mode)
+
+(defcustom web-mode-disable-css-colorization (not (display-graphic-p))
+  "In a CSS block, do not set background according to the color: #xxx, rgb(x,x,x)."
+  :type 'boolean
+  :group 'web-mode)
+
+(defcustom web-mode-disable-auto-indentation (not (display-graphic-p))
+  "Disable auto-indentation."
+  :type 'boolean
+  :group 'web-mode)
+
+(defcustom web-mode-disable-auto-pairing (not (display-graphic-p))
+  "Disable auto-pairing."
+  :type 'boolean
+  :group 'web-mode)
+
+(defcustom web-mode-enable-whitespaces nil
+  "Enable whitespaces."
+  :type 'boolean
+  :group 'web-mode)
+
+(defcustom web-mode-enable-block-face nil
+  "Enable block face (useful for setting a background for example).
+See web-mode-block-face."
+  :type 'boolean
+  :group 'web-mode)
+
+(defcustom web-mode-enable-part-face nil
+  "Enable part face (useful for setting a background for example).
+See web-mode-part-face."
+  :type 'boolean
+  :group 'web-mode)
+
+(defcustom web-mode-enable-heredoc-fontification nil
+  "Enable heredoc fontification. The identifier should contain JS, JAVASCRIPT or HTML."
+  :type 'boolean
+  :group 'web-mode)
+
+(defcustom web-mode-enable-comment-keywords nil
+  "Enable highlight of keywords like FIXME, TODO, etc. in comments."
+  :type 'list
+  :group 'web-mode)
+
+(defcustom web-mode-comment-style 1
+  "Comment style : 2 = server comments."
+  :type 'integer
+  :group 'web-mode)
+
+(defcustom web-mode-indent-style 2
+  "Indentation style.
+with value 2, HTML lines beginning text are also indented (do not forget side effects, ie. content of a textarea)."
+  :type 'integer
+  :group 'web-mode)
+
+(defcustom web-mode-tag-auto-close-style 1
+  "Tag auto-close style:
+0=no auto-closing
+1=auto-close with </
+2=auto-close with > and </."
+  :type 'integer
+  :group 'web-mode)
+
+(defcustom web-mode-extra-php-constants '()
+  "A list of additional strings to treat as PHP constants."
+  :type 'list
+  :group 'web-mode)
+
+(defcustom web-mode-extra-php-keywords '()
+  "A list of additional strings to treat as PHP keywords."
+  :type 'list
+  :group 'web-mode)
+
+(defcustom web-mode-extra-jsp-keywords '()
+  "A list of additional strings to treat as JSP keywords."
+  :type 'list
+  :group 'web-mode)
+
+(defcustom web-mode-extra-python-keywords '()
+  "A list of additional strings to treat as Python keywords."
+  :type 'list
+  :group 'web-mode)
+
+(defcustom web-mode-extra-erb-keywords '()
+  "A list of additional strings to treat as ERB keywords."
+  :type 'list
+  :group 'web-mode)
+
+(defcustom web-mode-extra-asp-constants '()
+  "A list of additional strings to treat as ASP constants."
+  :type 'list
+  :group 'web-mode)
+
+(defcustom web-mode-extra-asp-keywords '()
+  "A list of additional strings to treat as ASP keywords."
+  :type 'list
+  :group 'web-mode)
+
+(defcustom web-mode-extra-asp-types '()
+  "A list of additional strings to treat as ASP types."
+  :type 'list
+  :group 'web-mode)
+
+(defcustom web-mode-extra-aspx-keywords '()
+  "A list of additional strings to treat as ASPX keywords."
+  :type 'list
+  :group 'web-mode)
+
+(defcustom web-mode-extra-javascript-keywords '()
+  "A list of additional strings to treat as JS keywords."
+  :type 'list
+  :group 'web-mode)
+
+(defcustom web-mode-extra-razor-keywords '()
+  "A list of additional strings to treat as Razor keywords."
+  :type 'list
+  :group 'web-mode)
+
+(defcustom web-mode-extra-comment-keywords '()
+  "A list of additional strings to treat as comment keywords."
+  :type 'list
+  :group 'web-mode)
+
+(defface web-mode-warning-face
+  '((t :inherit font-lock-warning-face))
+  "Face for warning."
+  :group 'web-mode-faces)
+
+(defface web-mode-preprocessor-face
+  '((t :inherit font-lock-preprocessor-face))
+  "Face for preprocessor."
+  :group 'web-mode-faces)
+
+(defface web-mode-block-control-face
+  '((t :inherit font-lock-preprocessor-face))
+  "Face for preprocessor."
+  :group 'web-mode-faces)
+
+(defface web-mode-builtin-face
+  '((t :inherit font-lock-builtin-face))
+  "Face for builtins."
+  :group 'web-mode-faces)
+
+(defface web-mode-symbol-face
+  '((t :foreground "gold"))
+  "Face for symbols."
+  :group 'web-mode-faces)
+
+(defface web-mode-doctype-face
+  '((t :foreground "Grey"))
+  "Face for HTML doctype."
+  :group 'web-mode-faces)
+
+(defface web-mode-html-tag-face
+  '((t :foreground "Snow4"))
+  "Face for HTML tags."
+  :group 'web-mode-faces)
+
+(defface web-mode-html-attr-name-face
+  '((t :foreground "Snow3"))
+  "Face for HTML attribute names (including =)."
+  :group 'web-mode-faces)
+
+(defface web-mode-html-attr-value-face
+  '((t :inherit font-lock-string-face))
+  "Face for HTML attribute values."
+  :group 'web-mode-faces)
+
+(defface web-mode-block-attr-name-face
+  '((t :inherit web-mode-html-attr-name-face))
+  "Face for block attribute names."
+  :group 'web-mode-faces)
+
+(defface web-mode-block-attr-value-face
+  '((t :inherit web-mode-html-attr-value-face))
+  "Face for block attribute values."
+  :group 'web-mode-faces)
+
+(defface web-mode-css-selector-face
+  '((t :inherit font-lock-keyword-face))
+  "Face for CSS rules."
+  :group 'web-mode-faces)
+
+(defface web-mode-css-pseudo-class-face
+  '((t :inherit font-lock-builtin-face))
+  "Face for CSS pseudo-classes."
+  :group 'web-mode-faces)
+
+(defface web-mode-css-at-rule-face
+  '((t :inherit font-lock-constant-face))
+  "Face for CSS at-rules."
+  :group 'web-mode-faces)
+
+(defface web-mode-css-property-name-face
+  '((t :inherit font-lock-variable-name-face))
+  "Face for CSS props."
+  :group 'web-mode-faces)
+
+(defface web-mode-css-color-face
+  '((t :inherit font-lock-builtin-face))
+  "Face for CSS colors (#xxx)."
+  :group 'web-mode-faces)
+
+(defface web-mode-css-priority-face
+  '((t :inherit font-lock-builtin-face))
+  "Face for CSS priority (!important)."
+  :group 'web-mode-faces)
+
+(defface web-mode-css-function-face
+  '((t :inherit font-lock-builtin-face))
+  "Face for CSS functions."
+  :group 'web-mode-faces)
+
+(defface web-mode-variable-name-face
+  '((t :inherit font-lock-variable-name-face))
+  "Face for variable names."
+  :group 'web-mode-faces)
+
+(defface web-mode-function-name-face
+  '((t :inherit font-lock-function-name-face))
+  "Face for function names."
+  :group 'web-mode-faces)
+
+(defface web-mode-string-face
+  '((t :inherit font-lock-string-face))
+  "Face for strings."
+  :group 'web-mode-faces)
+
+(defface web-mode-block-string-face
+  '((t :inherit web-mode-string-face))
+  "Face for block strings."
+  :group 'web-mode-faces)
+
+(defface web-mode-part-string-face
+  '((t :inherit web-mode-string-face))
+  "Face for part strings."
+  :group 'web-mode-faces)
+
+(defface web-mode-javascript-string-face
+  '((t :inherit web-mode-string-face))
+  "Face for javascript strings."
+  :group 'web-mode-faces)
+
+(defface web-mode-css-string-face
+  '((t :inherit web-mode-string-face))
+  "Face for css strings."
+  :group 'web-mode-faces)
+
+(defface web-mode-json-key-face
+  '((t :foreground "plum"))
+  "Face for json key strings."
+  :group 'web-mode-faces)
+
+(defface web-mode-json-context-face
+  '((t :foreground "orchid3"))
+  "Face for json context strings."
+  :group 'web-mode-faces)
+
+(defface web-mode-json-string-face
+  '((t :inherit web-mode-string-face))
+  "Face for json strings."
+  :group 'web-mode-faces)
+
+(defface web-mode-comment-face
+  '((t :inherit font-lock-comment-face))
+  "Face for comments."
+  :group 'web-mode-faces)
+
+(defface web-mode-block-comment-face
+  '((t :inherit web-mode-comment-face))
+  "Face for server comments."
+  :group 'web-mode-faces)
+
+(defface web-mode-part-comment-face
+  '((t :inherit web-mode-comment-face))
+  "Face for part comments."
+  :group 'web-mode-faces)
+
+(defface web-mode-constant-face
+  '((t :inherit font-lock-constant-face))
+  "Face for language constants."
+  :group 'web-mode-faces)
+
+(defface web-mode-type-face
+  '((t :inherit font-lock-type-face))
+  "Face for language types."
+  :group 'web-mode-faces)
+
+(defface web-mode-keyword-face
+  '((t :inherit font-lock-keyword-face))
+  "Face for language keywords."
+  :group 'web-mode-faces)
+
+(defface web-mode-param-name-face
+  '((t :foreground "Snow3"))
+  "Face for server attribute names."
+  :group 'web-mode-faces)
+
+(defface web-mode-whitespace-face
+  '((t :background "DarkOrchid4"))
+  "Face for whitespaces."
+  :group 'web-mode-faces)
+
+(defface web-mode-block-face
+  '((((class color) (min-colors 88) (background dark))
+     :background "grey18")
+    (((class color) (min-colors 88) (background light))
+     :background "LightYellow1")
+    (((class color) (min-colors 16) (background dark))
+     :background "grey18")
+    (((class color) (min-colors 16) (background light))
+     :background "LightYellow1")
+    (((class color) (min-colors 8))
+     :background "Black")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :background "grey"))
+  "Face for blocks (useful for setting a background for example).
+Must be used in conjunction with web-mode-enable-block-face."
+  :group 'web-mode-faces)
+
+(defface web-mode-part-face
+  '((t :inherit web-mode-block-face))
+  "Face for parts."
+  :group 'web-mode-faces)
+
+(defface web-mode-folded-face
+  '((t :underline t))
+  "Overlay face for folded."
+  :group 'web-mode-faces)
+
+(defface web-mode-comment-keyword-face
+  '((t :weight bold :box t))
+  "Comment keywords."
+  :group 'web-mode-faces)
+
+(defvar web-mode-void-elements
+  '("area" "base" "br" "col" "command" "embed" "hr" "img" "input" "keygen"
+    "link" "meta" "param" "source" "track" "wbr")
+  "Void (self-closing) tags.")
+
+(defvar web-mode-text-properties
+  '(part-side nil part-token nil part-language nil tag-name nil tag-type nil tag-beg nil tag-end nil block-side nil block-token nil block-beg nil block-end nil face nil)
+  "Text properties used for fontification and indentation.")
+
+(defvar web-mode-text-properties2
+  '(part-side nil part-token nil part-language nil tag-name nil tag-type nil tag-beg nil tag-end nil face nil)
+  "Text properties used for fontification and indentation.")
+
+(defvar web-mode-large-embed-threshold 512
+  "Threshold for large part/block.")
+
+(defvar web-mode-has-any-large-part nil
+  "Does the current buffer has large parts ?")
+
+(defvar web-mode-has-any-large-block nil
+  "Does the current buffer has large blocks ?")
+
+(defvar web-mode-is-scratch nil
+  "Is scratch buffer ?")
+
+(defvar web-mode-time nil
+  "For benchmarking")
+
+(defvar web-mode-expand-initial-pos nil
+  "First mark pos.")
+
+(defvar web-mode-expand-previous-state ""
+  "Last mark state.")
+
+(defvar web-mode-tag-regexp "<\\(/?[[:alpha:]][[:alnum:]]*\\)"
+  "Regular expression for HTML/XML tag.")
+
+(defvar web-mode-start-tag-regexp "<\\([[:alpha:]][[:alnum:]]*\\)"
+  "Regular expression for HTML/XML start tag.")
+
+(defvar web-mode-whitespaces-regexp
+  "^[ \t]\\{2,\\}$\\| \t\\|\t \\|[ \t]+$\\|^[ \n\t]+\\'\\|^[ \t]?[\n]\\{2,\\}"
+  "Regular expression for whitespaces.")
+
+(defvar web-mode-engine nil
+  "Template engine")
+
+(defvar web-mode-engines
+  '(("asp"        . ("asp"))
+    ("aspx"       . ("aspx"))
+    ("blade"      . ("laravel"))
+    ("closure"    . ("soy"))
+    ("ctemplate"  . ("mustache" "handlebars" "hapax" "ngtemplate" "ember" "kite"))
+    ("django"     . ("dtl" "twig" "swig" "jinja" "jinja2" "erlydtl"))
+    ("dust"       . ("dustjs"))
+    ("erb"        . ("eruby" "erubis"))
+    ("go"         . ("gtl"))
+    ("jsp"        . ())
+    ("python"     . ())
+    ("razor"      . ("play" "play2"))
+    ("underscore" . ("underscorejs"))
+    ("velocity"   . ("vtl" "cheetah")))
+  "Engine name aliases")
+
+(defvar web-mode-content-types
+  '(("css"        . "\\.css\\'")
+    ("javascript" . "\\.js\\'")
+    ("json"       . "\\.\\(json\\|jsonld\\)\\'")
+    ("html"       . "."))
+  "content types")
+
+(defvar web-mode-engine-file-regexps
+  '(("asp"              . "\\.asp\\'")
+    ("aspx"             . "\\.as[cp]x\\'")
+    ("blade"            . "\\.blade")
+    ("closure"          . "\\.soy\\'")
+    ("ctemplate"        . "\\.\\(chtml\\)\\'")
+    ("django"           . "\\.\\(djhtml\\|tmpl\\|dtl\\)\\'")
+    ("django"           . "twig")
+    ("dust"             . "\\.dust\\'")
+    ("erb"              . "\\.\\(erb\\|rhtml\\)\\'")
+    ("freemarker"       . "\\.ftl\\'")
+    ("go"               . "\\.go\\(html\\|tmpl\\)\\'")
+    ("handlebars"       . "\\(handlebars\\|.\\hbs\\'\\)")
+    ("jsp"              . "\\.jsp\\'")
+    ("mustache"         . "\\.mustache\\'")
+    ("php"              . "\\.\\(php\\|ctp\\|psp\\|inc\\)\\'")
+    ("python"           . "\\.pml\\'")
+    ("razor"            . "play\\|\\.scala\\.\\|\\.cshtml\\'\\|\\.vbhtml\\'")
+    ("smarty"           . "\\.tpl\\'")
+    ("template-toolkit" . "\\.tt.?\\'")
+    ("underscore"       . "\\.underscore\\'")
+    ("velocity"         . "\\.\\(vsl\\|vtl\\|vm\\)\\'"))
+  "Engine file extensions.")
+
+(defvar web-mode-smart-quotes
+  '("«" . "»")
+  "Preferred smart quotes")
+
+(defvar web-mode-xml-chars
+  '((?\& . "&amp;")
+    (?\< . "&lt;")
+    (?\> . "&gt;"))
+  "XML chars")
+
+(defvar web-mode-html-entities
+  '(("eacute" . "é")
+    ("egrave" . "è")
+    ("middot" . "·")
+    ("quot"   . "\"")
+    ("amp"    . "&")
+    ("lt"     . "<")
+    ("gt"     . ">")
+    ("laquo"  . "«")
+    ("raquo"  . "»")
+    ("lsquo"  . "‘")
+    ("rsquo"  . "’")
+    ("ldquo"  . "“")
+    ("rdquo"  . "”")
+    ("apos"   . "'"))
+  "HTML entities")
+
+(defvar web-mode-snippets
+  (list
+   '("table"
+     "<table><tbody>\n<tr>\n<td>"
+     "</td>\n<td></td>\n</tr>\n</tbody></table>")
+   '("ul"
+     "<ul>\n<li>"
+     "</li>\n<li></li>\n</ul>")
+   '("if"
+     "<?php if ( as ): ?>\n"
+     "\n<?php endif; ?>")
+   '("for"
+     "<?php for ( ; ; ): ?>\n"
+     "\n<?php endfor; ?>")
+   '("foreach"
+     "<?php foreach ( as ): ?>\n"
+     "\n<?php endforeach; ?>")
+   '("html5"
+     "<!doctype html>\n<html>\n<head>\n<title></title>\n<meta charset=\"utf-8\" />\n</head>\n<body>\n"
+     "\n</body>\n</html>")
+   )
+  "Code snippets")
+
+;; todo : dynamically construct according to engine
+(defvar web-mode-auto-pairs
+  (list
+   '("<?p"  "hp  ?>"   "\\?>"  3)
+   '("<? "  "?>"       "\\?>"  0)
+   '("<?="  "?>"       "\\?>"  0)
+   '("<!-"  "-  -->"   "--"    2)
+;; underscrore js conflict
+;;   '("<%-"  "-  --%>"  "--"    2)
+   '("<%@"  "  %>"     "%>"    1)
+   '("<%="  "%>"       "%>"    0)
+   '("<% "  " %>"      "%>"    0)
+   '("{{ "  " }}"      "}}"    0)
+   '("{% "  " %}"      "%}"    0)
+   '("{# "  " #}"      "#}"    0)
+   '("[% "  " %]"      "%]"    0)
+   '("[# "  " #]"      "#]"    0)
+   )
+  "Auto-Pairs")
+
+(defvar web-mode-content-type ""
+  "Buffer file type.")
+
+(defvar web-mode-comments-invisible nil
+  "Comments visbility.")
+
+(defvar web-mode-is-narrowed nil
+  "Buffer has been narrowed.")
+
+(defvar web-mode-hook nil
+  "List of functions to be executed with web-mode.")
+
+(defvar web-mode-buffer-highlighted nil
+  "Is buffer highlighted.")
+
+(defvar web-mode-display-table nil
+  "Display table.")
+
+(defvar web-mode-hl-line-mode-flag nil
+  "Is hl-line-mode enabled ?")
+
+(defvar web-mode-blade-active-blocks
+  '("else" "elseif" "foreach" "forelse" "for" "if" "section" "stop" "unless" "while")
+  "Blade controls.")
+
+(defvar web-mode-closure-active-blocks
+  '("call" "case" "default" "deltemplate" "else" "elseif" "for" "foreach"
+    "if" "ifempty" "let" "literal" "msg" "param" "switch" "template")
+  "Closure controls.")
+
+(defvar web-mode-django-active-blocks
+  '("assets" "autoescape" "block" "cache" "call" "comment"
+    "elif" "else" "elseif" "embed" "empty" "filter" "foreach" "for"
+    "ifchanged" "ifequal" "ifnotequal" "if"
+    "macro" "draw" "random" "sandbox" "spaceless" "trans" "verbatim" "with")
+  "Django controls.")
+
+(defvar web-mode-go-active-blocks
+  '("else" "end" "if" "range" "with")
+  "Go controls.")
+
+(defvar web-mode-php-active-blocks
+  '("declare" "else" "elseif" "for" "foreach" "if" "while")
+  "PHP controls.")
+
+(defvar web-mode-smarty-active-blocks
+  '("block" "else" "elseif" "foreach" "for" "if" "section" "while")
+  "Smarty controls.")
+
+(defvar web-mode-velocity-active-blocks
+  '("define" "else" "elseif" "end" "for" "foreach" "if" "macro")
+  "Velocity controls.")
+
+(defvar web-mode-active-block-regexps
+  (list
+   (cons "asp"        "----")
+   (cons "aspx"       "----")
+   (cons "blade"      (concat "@\\(end\\)?" (regexp-opt web-mode-blade-active-blocks t)))
+   (cons "closure"    (concat "{/?" (regexp-opt web-mode-closure-active-blocks t)))
+   (cons "ctemplate"  "{{[#^/]\\([[:alnum:]_]+\\)")
+   (cons "django"     (concat "{%[-]?[ ]+\\(end\\)?" (regexp-opt web-mode-django-active-blocks t)))
+   (cons "dust"       "{[#/:?@><+^]\\([[:alpha:]_]+\\)")
+   (cons "erb"        "<%[-=]?[ ]+\\(.* do \\|for\\|unless\\|end\\|if\\|else\\)")
+   (cons "freemarker" "</?\\([[:alpha:]]+:[[:alpha:]]+\\)\\|[[<]/?[@#]\\([[:alpha:]]+\\)")
+   (cons "go"         (concat "{{[ ]*" (regexp-opt web-mode-go-active-blocks t)))
+   (cons "jsp"        "</?\\([[:alpha:]]+:[[:alpha:]]+\\)\\|<%[ ]*+\\(if\\|for\\|while\\|} else {\\)")
+   (cons "php"        (concat "<\\?\\(php[ ]+\\|[ ]*\\)?\\(end\\)?" (regexp-opt web-mode-php-active-blocks t)))
+   (cons "razor"      "----")
+   (cons "smarty"     (concat "{/?" (regexp-opt web-mode-smarty-active-blocks t)))
+   (cons "template-toolkit" (concat "\\[% " (regexp-opt '("foreach" "if" "else" "elsif" "filter" "end") t)))
+   (cons "underscore" "<%")
+   (cons "velocity"   (concat "#" (regexp-opt web-mode-velocity-active-blocks t))))
+  "Engine control regexps")
+
+(defvar web-mode-close-block-regexps
+  '(("asp"              . "----")
+    ("aspx"             . "----")
+    ("blade"            . "@\\\(end\\|else\\|stop\\)")
+    ("closure"          . "{\\(/\\|else\\|case\\|default\\|ifempty\\)")
+    ("ctemplate"        . "{{/")
+    ("django"           . "{%[-]?[ ]+\\(end\\|else\\|elseif\\|elif\\|empty\\)")
+    ("dust"             . "{\\(/\\|:else\\)")
+    ("erb"              . "<%[-]?[ ]+\\(end\\|else\\)")
+    ("freemarker"       . "[<[]\\(/#\\|#els\\|#break\\)")
+    ("go"               . "{{[ ]*\\(end\\|else\\)")
+    ("jsp"              . "</\\|<% }")
+    ("php"              . "<\\?\\(php[ ]+\\|[ ]*\\)?\\(end\\|else\\|}\\)")
+    ("razor"            . "}")
+    ("smarty"           . "{\\(/\\|else\\)")
+    ("template-toolkit" . "\\[% \\(end\\|els\\)")
+    ("underscore"       . "<% }")
+    ("velocity"         . "#\\(end\\|else\\)"))
+  "Close control blocks.")
+
+(defvar web-mode-block-regexps
+  '(("asp"              . "<%")
+    ("aspx"             . "<%")
+    ("blade"            . "{{\\|^[ \t]*@[[:alpha:]]")
+    ("closure"          . "{.\\|/\\*\\| //")
+    ("ctemplate"        . "[$]?{{.")
+    ("django"           . "{[#{%].")
+    ("dust"             . "{.")
+    ("erb"              . "<%\\|^%.")
+    ("freemarker"       . "<%\\|${\\|</?[[:alpha:]]+:[[:alpha:]]\\|</?[@#].\\|\\[/?[@#].")
+    ("go"               . "{{.")
+    ("jsp"              . "<%\\|${\\|</?[[:alpha:]]+:[[:alpha:]]")
+    ("php"              . "<\\?")
+    ("python"           . "<\\?")
+    ("razor"            . "@.")
+    ("smarty"           . "{[[:alpha:]#$/*\"]")
+    ("template-toolkit" . "\\[[%#]")
+    ("underscore"       . "<%")
+    ("velocity"         . "^[ \t]*#[[:alpha:]#*]\\|$[[:alpha:]!{]"))
+  "Engine block regexps.")
+
+(defvar web-mode-block-electric-chars
+  (list
+   (cons "blade"      '(?\{ ?\@))
+   (cons "closure"    '(?\{ ?\/))
+   (cons "ctemplate"  '(?\{ ?\$))
+   (cons "django"     '(?\{))
+   (cons "dust"       '(?\{))
+   (cons "erb"        '(?\%))
+   (cons "freemarker" '(?\[))
+   (cons "go"         '(?\{))
+   (cons "jsp"        '(?\$))
+   (cons "razor"      '(?\@))
+   (cons "smarty"     '(?\{))
+   (cons "velocity"   '(?\# ?\$)))
+  "Block electric chars.")
+
+(defvar web-mode-block-regexp nil
+  "Regular expression for identifying blocks.")
+
+(defvar web-mode-active-block-regexp nil
+  "Engine control regexp")
+
+(defvar web-mode-close-block-regexp nil
+  "Engine end control regexp")
+
+(defvar web-mode-engine-control-matcher nil
+  "Engine control match")
+
+(defvar web-mode-electric-chars nil
+  "electric chars")
+
+(defvar web-mode-comment-keywords
+  (regexp-opt
+   (append web-mode-extra-comment-keywords
+           '("FIXME" "TODO" "BUG" "KLUDGE" "WORKAROUND"
+             "OPTIMIZE" "HACK" "REFACTOR")))
+  "Comment keywords.")
+
+(defvar web-mode-php-constants
+  (regexp-opt
+   (append web-mode-extra-php-constants
+           '("TRUE" "FALSE" "NULL" "true" "false" "null"
+             "STR_PAD_LEFT" "STR_PAD_RIGHT"
+             "ENT_COMPAT" "ENT_QUOTES" "ENT_NOQUOTES" "ENT_IGNORE"
+             "ENT_SUBSTITUTE" "ENT_DISALLOWED" "ENT_HTML401" "ENT_XML1"
+             "ENT_XHTML" "ENT_HTML5"
+             "LIBXML_NOBLANKS")))
+  "PHP constants.")
+
+(defvar web-mode-php-keywords
+  (regexp-opt
+   (append web-mode-extra-php-keywords
+           '("and" "array" "as" "break"
+             "callable" "case" "catch"  "catch all" "class" "const" "continue"
+             "default" "die" "do"
+             "echo" "else" "elseif" "empty"
+             "endfor" "endforeach" "endif" "endswitch" "endwhile" "exit" "extends"
+             "finally" "for" "foreach" "function" "global" "goto"
+             "if" "include" "include_once" "instanceof" "interface" "isset"
+             "list" "next" "new" "or"
+             "private" "protected" "public"
+             "require" "require_once" "return" "static" "switch" "try" "throw" "unset" "use"
+             "var" "when" "while" "xor" "yield")))
+  "PHP keywords.")
+
+(defvar web-mode-php-types
+  (eval-when-compile
+    (regexp-opt
+     '("array" "bool" "boolean" "char" "const" "double" "float"
+       "int" "integer" "long" "mixed" "object" "real" "string"
+       "Exception")))
+  "PHP types.")
+
+(defvar web-mode-css-at-rules
+  (eval-when-compile
+    (regexp-opt
+     '("charset" "import" "media" "page" "font-face"
+       "namespace" "supports" "document"
+       "keyframes" "-moz-keyframes" "-webkit-keyframes")))
+  "CSS at-rules.")
+
+(defvar web-mode-css-pseudo-classes
+  (eval-when-compile
+    (regexp-opt
+     '("active" "after" "before" "checked" "disabled" "empty" "enabled"
+       "first" "first-child" "first-letter" "first-line" "first-of-type" "focus"
+       "hover" "lang" "last-child" "last-of-type" "left" "link"
+       "not" "nth-child" "nth-last-child" "nth-last-of-type" "nth-of-type"
+       "only-child" "only-of-type"
+       "right" "root" "selection" "target" "visited")))
+  "CSS pseudo-classes (and pseudo-elements).")
+
+(defvar web-mode-python-keywords
+  (regexp-opt
+   (append web-mode-extra-python-keywords
+           '("False" "class" "finally" "is" "return"
+             "None" "continue" "for" "lambda" "try"
+             "True" "def" "from" "nonlocal" "while"
+             "and" "del" "global" "not" "with"
+             "as" "elif" "if" "or" "yield"
+             "assert" "else" "import" "pass"
+             "break" "except" "in" "raise")))
+  "Python keywords.")
+
+(defvar web-mode-jsp-keywords
+  (regexp-opt
+   (append web-mode-extra-jsp-keywords
+           '("case" "catch" "do" "else" "end" "false" "for" "function"
+             "if" "in" "include" "new"
+             "package" "page" "private" "protected" "public"
+             "return" "tag" "taglib" "throw" "throws" "true" "try"
+             "void" "while")))
+  "JSP keywords.")
+
+(defvar web-mode-erb-keywords
+  (regexp-opt
+   (append web-mode-extra-erb-keywords
+           '("alias" "and" "begin" "break" "case" "class"
+             "def" "defined?" "do" "elsif" "else" "end" "ensure"
+             "fail" "for" "if" "in" "module" "next" "not"
+             "or" "redo" "rescue" "retry" "return" "then" "super"
+             "unless" "undef" "until" "when" "while" "yield"
+             "__ENCODING__" "__FILE__" "__LINE__"
+             )))
+  "ERB keywords.")
+
+(defvar web-mode-erb-builtins
+  (regexp-opt
+   '("__callee__" "__dir__" "__method__"
+     "abort" "at_exit" "autoload" "autoload?"
+     "binding" "block_given?" "caller" "catch"
+     "eval" "exec" "exit" "exit!" "fail" "fork" "format"
+     "lambda" "load" "loop" "open"
+     "p" "print" "printf" "proc" "putc" "puts"
+     "raise" "rand" "readline" "readlines" "require" "require_relative"
+     "sleep" "spawn" "sprintf" "srand" "syscall" "system"
+     "throw" "trap" "warn"
+     "alias_method" "attr" "attr_accessor" "attr_reader" "attr_writer"
+     "define_method" "extend" "include" "module_function"
+     "prepend" "private" "protected" "public"
+     "refine" "using"
+
+     "error_message_on" "error_messages_for" "form" "input"
+     "auto_discovery_link_tag" "image_tag" "javascript_include_tag"
+     "stylesheet_link_tag" "image_path" "path_to_image"" "
+     "javascript_path" "path_to_javascript" "register_javascript_expansion"
+     "register_javascript_include_default" "register_stylesheet_expansion"
+     "stylesheet_path" "path_to_stylesheet" "atom_feed" "entry" "updated"
+     "benchmark" "cache" "capture" "content_for" "distance_of_time_in_words"
+     "distance_of_time_in_words_to_now" "time_ago_in_words" "date_select"
+     "datetime_select" "time_select" "select_date" "select_datetime"
+     "select_day" "select_hour" "select_minute" "select_month" "select_second"
+     "select_time" "select_year" "debug"
+     "check_box" "fields_for" "file_field" "form_for" "hidden_field"
+     "label" "password_field" "radio_button" "text_area" "text_field"
+     "check_box_tag" "field_set_tag" "file_field_tag" "form_tag"
+     "hidden_field_tag" "image_submit_tag" "label_tag" "password_field_tag"
+     "radio_button_tag" "select_tag" "submit_tag" "text_area_tag"
+     "text_field_tag"
+     "collection_select" "country_options_for_select" "country_select"
+     "option_groups_from_collection_for_select" "options_for_select"
+     "options_from_collection_for_select" "select"
+     "time_zone_options_for_select"
+     "time_zone_select" "button_to_function" "define_javascript_functions"
+     "escape_javascript" "javascript_tag" "link_to_function"" "
+     "number_to_currency" "number_to_human_size" "number_to_percentage"
+     "number_to_phone" "number_with_delimiter" "number_with_precision"
+     "evaluate_remote_response" "form_remote_for" "form_remote_tag"
+     "link_to_remote" "observe_field" "observe_field"
+     "periodically_call_remote"
+     "remote_form_for" "remote_function" "submit_to_remote" "update_page"
+     "update_page_tag" "dom_class" "dom_id" "partial_path" "sanitize"
+     "sanitize_css" "strip_links" "strip_tags"
+     "cdata_section" "content_tag" "escape_once" "tag"
+     "auto_link" "concat" "cycle" "excerpt" "highlight" "markdown" "pluralize"
+     "reset_cycle" "simple_format" "textilize" "textilize_without_paragraph"
+     "truncate" "word_wrap" "button_to" "current_page?" "link_to" "link_to_if"
+     "link_to_unless" "link_to_unless_current" "mail_to" "url_for"
+
+     ))
+  "ERB builtins.")
+
+(defvar web-mode-asp-constants
+  (regexp-opt
+   (append web-mode-extra-asp-constants
+           '("adAsyncExecute" "adAsyncFetch" "adAsyncFetchNonBlocking" "adCmdFile" "adCmdStoredProc" "adCmdTable" "adCmdTableDirect" "adCmdText" "adCmdUnknown"
+             "adCmdUnspecified" "adExecuteNoRecords" "adExecuteRecord" "adExecuteStream" "adLockBatchOptimistic" "adLockOptimistic" "adLockPessimistic"
+             "adLockReadOnly" "adLockUnspecified" "adOpenDynamic" "adOpenForwardOnly" "adOpenKeyset" "adOpenStatic" "adOpenUnspecified" "adOptionUnspecified"
+             "Empty" "Nothing" "Null" "True" "False"
+             "vbBack" "vbCr" "vbCrLf" "vbFormFeed" "vbLf" "vbNewLine" "vbNullChar" "vbNullString" "vbObjectError" "vbScript" "vbTab" "vbVerticalTab")))
+  "ASP constants.")
+
+(defvar web-mode-asp-keywords
+  (regexp-opt
+   (append web-mode-extra-asp-keywords
+           '("Abs" "And" "Array" "Asc" "Atn"
+             "CBool" "CByte" "CCur" "CDate" "CDbl" "CInt" "CLng" "CSng" "CStr"
+             "Call" "Case" "Chr" "Class" "Const" "Cos" "CreateObject"
+             "Date" "DateAdd" "DateDiff" "DatePart" "DateSerial" "DateValue"
+             "Day" "Dim" "Do"
+             "Each" "Else" "ElseIf" "End" "Erase" "Err" "Eval" "Exit" "Exp"
+             "Explicit"
+             "Filter" "Fix" "For" "FormatCurrency" "FormatDateTime"
+             "FormatNumber" "FormatPercent" "Function"
+             "GetLocale" "GetObject" "GetRef" "Hex" "Hour"
+             "If" "In" "InStr" "InStrRev" "InputBox" "Int" "IsArray" "IsDate"
+             "IsEmpty" "IsNull" "IsNumeric" "IsObject" "Join"
+             "LBound" "LCase" "LTrim" "Language" "Left" "Len" "Let"
+             "LoadPicture" "Log" "Loop"
+             "Mid" "Minute" "Month" "MonthName" "MsgBox"
+             "New" "Next" "Not" "Now"
+             "Oct" "On" "Option" "Or" "Preserve" "Private" "Public"
+             "RGB" "RTrim" "Redim" "Rem" "Replace" "Right" "Rnd" "Round"
+             "ScriptEngine" "ScriptEngineBuildVersion"
+             "ScriptEngineMajorVersion" "ScriptEngineMinorVersion"
+             "Second" "Select" "Set" "SetLocale" "Sgn" "Sin" "Space" "Split"
+             "Sqr" "StrComp" "StrReverse" "String" "Sub"
+             "Tan" "Then" "Time" "TimeSerial" "TimeValue" "Timer" "To" "Trim"
+             "TypeName"
+             "UBound" "UCase" "Until" "VarType"
+             "Weekday" "WeekdayName" "Wend" "With" "While" "Year")))
+  "ASP keywords.")
+
+(defvar web-mode-asp-types
+  (regexp-opt
+   (append web-mode-extra-asp-types
+           '("Application" "ASPError" "Request" "Response" "Server" "Session")))
+  "ASP types.")
+
+(defvar web-mode-aspx-keywords
+  (regexp-opt
+   (append web-mode-extra-aspx-keywords
+           '("case" "catch" "do" "else" "end"
+             "for" "foreach" "function"
+             "if" "in" "include"
+             "new" "package" "page" "return"
+             "tag" "throw" "throws" "try" "while")))
+  "ASP.Net keywords.")
+
+(defvar web-mode-smarty-keywords
+  (regexp-opt
+   '("as"))
+  "Smarty keywords.")
+
+(defvar web-mode-velocity-keywords
+  (eval-when-compile
+    (regexp-opt
+     '("in")))
+  "Velocity keywords.")
+
+(defvar web-mode-freemarker-keywords
+  (eval-when-compile
+    (regexp-opt
+     '("as" "list"))))
+
+(defvar web-mode-go-keywords
+  (eval-when-compile
+    (regexp-opt
+     '("define" "else" "end" "if" "pipeline" "range" "template" "with"))))
+
+(defvar web-mode-go-functions
+  (eval-when-compile
+    (regexp-opt
+     '("and" "call" "html" "index" "js" "len" "not" "or"
+       "print" "printf" "println" "urlquery")))
+  "Go functions.")
+
+(defvar web-mode-closure-keywords
+  (eval-when-compile
+    (regexp-opt
+     '("in" "and" "not" "or")
+     ))
+  "Closure keywords")
+
+(defvar web-mode-django-keywords
+  (eval-when-compile
+    (regexp-opt
+     '("and" "as" "autoescape" "block" "blocktrans" "break"
+       "cache" "call" "comment" "context" "continue" "csrf_token" "cycle"
+       "debug" "do"
+       "embed" "empty" "else" "elseif" "elif" "endautoescape" "endblock" "endcomment"
+       "endcache" "endcall" "endembed" "endfilter" "endfor" "endif"
+       "endifchanged" "endifequal" "endifnotequal" "endmacro" "endrandom" "endraw"
+       "endsandbox" "endset" "endspaceless" "endtrans" "endverbatim" "endwith"
+       "extends" "filter" "firstof" "flush" "for" "from"
+       "if" "ifchanged" "ifequal" "ifnotequal" "ignore" "import"
+       "in" "include" "is"
+       "load" "macro" "missing" "none" "not" "now" "or" "pluralize"
+       "random" "raw" "regroup" "trans"
+       "sandbox" "set" "spaceless" "ssi" "static" "templatetag" "trans"
+       "use" "url" "var" "verbatim" "widthratio" "with")))
+  "Django keywords.")
+
+(defvar web-mode-django-types
+  (eval-when-compile
+    (regexp-opt
+     '("null" "empty" "false" "true"
+       ))))
+
+(defvar web-mode-directives
+  (eval-when-compile
+    (regexp-opt
+     '("include" "page" "taglib"
+       "Assembly" "Control" "Implements" "Import"
+       "Master" "OutputCache" "Page" "Reference" "Register")))
+  "Directives.")
+
+(defvar web-mode-template-toolkit-keywords
+  (regexp-opt
+   '("block" "call" "case" "catch" "clear" "default" "do"
+     "else" "elsif" "end" "filter" "final" "for"
+     "foreach" "get" "if" "in" "include" "insert" "is" "last"
+     "macro" "meta" "or" "perl" "process" "rawperl" "return"
+     "set" "stop" "switch" "tags" "throw" "try"
+     "unless" "use" "while" "wrapper"))
+  "Template-toolkit keywords")
+
+(defvar web-mode-javascript-keywords
+  (regexp-opt
+   (append web-mode-extra-javascript-keywords
+           '("break" "case" "catch" "class" "const" "continue"
+             "debugger" "default" "delete" "do" "else" "enum" "eval"
+             "export" "extends" "finally" "for" "function" "if"
+             "implements" "import" "in" "instanceof" "interface" "let"
+             "new" "package" "private" "protected" "public"
+             "return" "static" "super" "switch" "throw"
+             "try" "typeof" "var" "void" "while" "with" "yield"
+             )))
+  "JavaScript keywords.")
+
+(defvar web-mode-javascript-constants
+  (regexp-opt
+   '("false" "null" "undefined"
+     "Infinity" "NaN"
+     "true" "arguments" "this"
+     ))
+  "JavaScript constants.")
+
+
+(defvar web-mode-razor-keywords
+  (regexp-opt
+   (append web-mode-extra-razor-keywords
+           '("false" "true" "foreach" "if" "in" "var" "for" "display")))
+  "Razor keywords.")
+
+(defvar web-mode-dust-font-lock-keywords
+  (list
+   '("/?}\\|{[#/:?@><+^]?" 0 'web-mode-preprocessor-face)
+   '("{[#:/?@><+^]\\([[:alpha:]_]+\\)" 1 'web-mode-block-control-face)
+   '(":\\([[:alpha:]]+\\)" 1 'web-mode-keyword-face)
+   '("\\<\\([[:alpha:]_]+=\\)\\(\"[^\"]*\"\\|[[:alnum:]_]*\\)"
+     (1 'web-mode-block-attr-name-face)
+     (2 'web-mode-block-attr-value-face))
+   '("\\\([[:alnum:]_]+\\)" 0 'web-mode-variable-name-face)
+   ))
+
+(defvar web-mode-template-toolkit-font-lock-keywords
+  (list
+   '("\\[%[-+]?\\|[-+=]?%\\]" 0 'web-mode-preprocessor-face)
+   (cons (concat "\\<\\(" web-mode-template-toolkit-keywords "\\)\\>")
+         '(1 'web-mode-keyword-face))
+   '("\\\([[:alpha:]][[:alnum:]_]+\\)[ ]?(" 1 'web-mode-function-name-face)
+   '("\\\([[:alpha:]][[:alnum:]_]+\\)" 0 'web-mode-variable-name-face)
+   ))
+
+(defvar web-mode-smarty-font-lock-keywords
+  (list
+   '("}\\|{/?" 0 'web-mode-preprocessor-face)
+   (cons (concat "[ ]\\(" web-mode-smarty-keywords "\\)[ ]") '(1 'web-mode-keyword-face))
+   '("{/?\\([[:alpha:]_]+\\)" 1 'web-mode-block-control-face)
+   '("\\<\\([$]\\)\\([[:alnum:]_]+\\)" (1 nil) (2 'web-mode-variable-name-face))
+   '("\\<\\(\\sw+\\)[ ]?(" 1 'web-mode-function-name-face)
+   '(" \\(\\sw+[ ]?=\\)" 1 'web-mode-param-name-face)
+   '(" \\(\\sw+\\)[ }]" 1 'web-mode-param-name-face)
+   '("|\\([[:alnum:]_]+\\)" 1 'web-mode-function-name-face)
+   '("\\(->\\)\\(\\sw+\\)" (1 nil) (2 'web-mode-variable-name-face))
+   '("[.]\\([[:alnum:]_-]+\\)[ ]?(" (1 'web-mode-function-name-face))
+   '("[.]\\([[:alnum:]_]+\\)" (1 'web-mode-variable-name-face))
+   '("#\\([[:alnum:]_]+\\)#" 1 'web-mode-variable-name-face)
+   ))
+
+(defvar web-mode-velocity-font-lock-keywords
+  (list
+   '("\\([#]\\)\\([[:alpha:]]+\\)\\>"
+     (1 'web-mode-preprocessor-face)
+     (2 'web-mode-block-control-face))
+   (cons (concat "[ ]\\(" web-mode-velocity-keywords "\\)[ ]") '(1 'web-mode-keyword-face t t))
+   '("#macro([ ]*\\([[:alpha:]]+\\)[ ]+" 1 'web-mode-function-name-face)
+   '("[.]\\([[:alnum:]_-]+\\)" 1 'web-mode-variable-name-face)
+   '("\\<\\($[!]?[{]?\\)\\([[:alnum:]_-]+\\)[}]?" (1 nil) (2 'web-mode-variable-name-face))
+   ))
+
+(defvar web-mode-django-expr-font-lock-keywords
+  (list
+   '("\\({{\\)[ ]?" 1 'web-mode-preprocessor-face)
+   '("[ ]?\\(}}\\)" 1 'web-mode-preprocessor-face)
+   '("|[ ]?\\([[:alpha:]]+\\)\\>" 1 'web-mode-function-name-face)
+   (cons (concat "\\<\\(" web-mode-django-types "\\)\\>") '(1 'web-mode-type-face))
+   '("\\<\\([[:alpha:]_]+\\)[ ]?(" 1 'web-mode-function-name-face)
+   '("[[:alnum:]_]+" 0 'web-mode-variable-name-face)
+   )
+  "Font lock keywords for dtl expr")
+
+(defvar web-mode-django-code-font-lock-keywords
+  (list
+   '("{%\\|%}" 0 'web-mode-preprocessor-face)
+   (cons (concat "\\<\\(" web-mode-django-keywords "\\)\\>") '(1 'web-mode-keyword-face))
+   (cons (concat "\\<\\(" web-mode-django-types "\\)\\>") '(1 'web-mode-type-face))
+   '("|[ ]?\\([[:alpha:]_]+\\)\\>" 1 'web-mode-function-name-face)
+;;   (cons (concat "|[ ]?\\(" web-mode-django-filters "\\)\\>") '(1 'web-mode-function-name-face t t))
+   '("\\<\\([[:alpha:]_]+\\)[ ]?(" 1 'web-mode-function-name-face)
+   '("[[:alnum:]_]+" 0 'web-mode-variable-name-face)
+   ))
+
+(defvar web-mode-ctemplate-font-lock-keywords
+  (list
+   '("${{\\|{{[>#/{%^&]?\\|[}]?}}" 0 'web-mode-preprocessor-face)
+   '("{{[#/>][ ]*\\([[:alnum:]_]+\\)" 1 'web-mode-block-control-face)
+   '("[[:alnum:]_]" 0 'web-mode-variable-name-face)
+   '("[ ]+\\([[:alnum:]_]+=\\)" 1 'web-mode-param-name-face t t)
+   '("[:=]\\([[:alpha:]_]+\\)" 1 'web-mode-function-name-face t t)
+   ))
+
+(defvar web-mode-razor-font-lock-keywords
+  (list
+   '("@" 0 'web-mode-preprocessor-face)
+   (cons (concat "\\<\\(" web-mode-razor-keywords "\\)\\>") '(1 'web-mode-keyword-face t t))
+   '("\\<\\([[:alnum:]_]+\\)[ ]?(" 1 'web-mode-function-name-face)
+   '("<\\([[:alnum:]_]+\\)>" 1 'web-mode-type-face)
+   '("\\<\\([[:alnum:].]+\\)[ ]+[{[:alpha:]]+" 1 'web-mode-type-face)
+   '("[[:alnum:]_]+" 0 'web-mode-variable-name-face)
+   ))
+
+(defvar web-mode-closure-font-lock-keywords
+  (list
+   '("{/?\\|/?}" 0 'web-mode-preprocessor-face)
+   '("{/?\\([[:alpha:]]+\\)" 1 'web-mode-block-control-face)
+   '("{param[ ]+\\([[:alnum:]]+\\)" 1 'web-mode-symbol-face)
+   '("\\<\\(true\\|false\\|null\\)\\>" 1 'web-mode-type-face)
+   (cons (concat "\\<\\(" web-mode-closure-keywords "\\)\\>") '(1 'web-mode-keyword-face))
+   '("{\\(alias\\|call\\|delcall\\|delpackage\\|deltemplate\\|namespace\\|template\\)[ ]+\\([[:alnum:].]+\\)" 2 'web-mode-constant-face)
+   '("\\(allowemptydefault\\|data\\|desc\\|meaning\\|autoescape\\|private\\|variant\\)=" 0 'web-mode-block-attr-name-face)
+   '("|\\([[:alpha:]]+\\)" 1 'web-mode-function-name-face)
+   '("\\<\\([[:alnum:]]+\\)[ ]?(" 1 'web-mode-function-name-face)
+   '("$\\([[:alnum:]._]+\\)" 1 'web-mode-variable-name-face)
+   ))
+
+(defvar web-mode-go-font-lock-keywords
+  (list
+   '("{{\\|}}" 0 'web-mode-preprocessor-face)
+   '("{{\\([[:alpha:]]+\\)" 1 'web-mode-block-control-face)
+   (cons (concat "\\<\\(" web-mode-go-keywords "\\)\\>") '(1 'web-mode-keyword-face))
+   (cons (concat "\\<\\(" web-mode-go-functions "\\)\\>") '(1 'web-mode-function-name-face))
+   '("[$.]\\([[:alnum:]_]+\\)" 1 'web-mode-variable-name-face t t)
+
+   ))
+
+(defvar web-mode-expression-font-lock-keywords
+  (list
+   '("<%\\$\\|%>" 0 'web-mode-preprocessor-face)
+   '("[[:alpha:]_]" 0 'web-mode-variable-name-face)
+   ))
+
+(defvar web-mode-selector-font-lock-keywords
+  (list
+   (cons (concat "@\\(" web-mode-css-at-rules "\\)\\>") '(1 'web-mode-css-at-rule-face))
+   '("\\<\\(all\|braille\\|embossed\\|handheld\\|print\\|projection\\|screen\\|speech\\|tty\\|tv\\|and\\|or\\)\\>" 1 'web-mode-keyword-face)
+   (cons (concat ":\\(" web-mode-css-pseudo-classes "\\)\\>") '(1 'web-mode-css-pseudo-class-face))
+   '("[[:alnum:]-]+" 0 'web-mode-css-selector-face)
+   '("\\[.*?\\]\\|(.*?)" 0 nil t t)
+   '("url(\\(.+?\\))" 1 'web-mode-string-face)
+   ))
+
+(defvar web-mode-declaration-font-lock-keywords
+  (list
+   (cons (concat "@\\(" web-mode-css-at-rules "\\)\\>") '(1 'web-mode-css-at-rule-face))
+   '("url(\\([^)]+\\)" 1 'web-mode-string-face)
+   '("\\([[:alpha:]-]\\{3,\\}\\)[ ]?:" 1 'web-mode-css-property-name-face)
+   '("\\([[:alpha:]-]+\\)[ ]?(" 1 'web-mode-css-function-face)
+   '("#[[:alnum:]]\\{1,6\\}" 0 'web-mode-css-color-face t t)
+   '("![ ]?important" 0 'web-mode-css-priority-face t t)
+   ))
+
+(defvar web-mode-html-font-lock-keywords
+  (list
+   '("</?[[:alnum:]]+\\|>" 0 'web-mode-html-tag-face)
+   '(" \\([[:alnum:]-]+=\\)\\(\"[^\"]+\"\\)"
+     (1 'web-mode-html-attr-name-face)
+     (2 'web-mode-html-attr-value-face))
+   ))
+
+(defvar web-mode-javascript-font-lock-keywords
+  (list
+   (cons (concat "\\<\\(" web-mode-javascript-keywords "\\)\\>") '(0 'web-mode-keyword-face))
+   (cons (concat "\\<\\(" web-mode-javascript-constants "\\)\\>") '(0 'web-mode-constant-face))
+   '("\\<\\(new\\|instanceof\\) \\([[:alnum:]_.]+\\)\\>" 2 'web-mode-type-face)
+   '("\\<\\([[:alnum:]_]+\\):[ ]*function[ ]*(" 1 'web-mode-function-name-face)
+   '("\\<function[ ]+\\([[:alnum:]_]+\\)" 1 'web-mode-function-name-face)
+   '("\\<\\(var\\)\\>[ ]+"
+     (1 'web-mode-keyword-face)
+     ("\\([[:alnum:]_]+\\)\\([ ]*=[^,;]*\\)?[,; ]" nil nil (1 'web-mode-variable-name-face)))
+   '("\\<\\(function\\)[ ]*("
+     (1 'web-mode-keyword-face)
+     ("\\([[:alnum:]_]+\\)\\([ ]*=[^,)]*\\)?[,)]" nil nil (1 'web-mode-variable-name-face)))
+   '("\\([[:alnum:]]+\\):" 1 'web-mode-variable-name-face)
+   '("/[^/]+/" 0 'web-mode-string-face)
+   ))
+
+(defvar web-mode-underscore-font-lock-keywords
+  (list
+   '("<%[-=]?\\|%>" 0 'web-mode-preprocessor-face)
+   (cons (concat "\\<\\(" web-mode-javascript-keywords "\\)\\>") '(0 'web-mode-keyword-face))
+   '("\\<\\(_\.[[:alpha:]]+\\)(" 1 'web-mode-function-name-face)
+   '("\\<new \\([[:alnum:]_.]+\\)\\>" 1 'web-mode-type-face)
+   '("\\<\\([[:alnum:]_]+\\):[ ]*function[ ]*(" 1 'web-mode-function-name-face)
+   '("\\<\\(var\\)\\>[ ]+\\([[:alnum:]_]+\\)"
+     (1 'web-mode-keyword-face)
+     (2 'web-mode-variable-name-face))
+   ))
+
+(defvar web-mode-asp-font-lock-keywords
+  (list
+   '("<%=?\\|%>" 0 'web-mode-preprocessor-face)
+   (cons (concat "\\<\\(" web-mode-asp-keywords "\\)\\>")
+         '(0 'web-mode-keyword-face))
+   (cons (concat "\\<\\(" web-mode-asp-types "\\)\\>")
+         '(0 'web-mode-type-face))
+   (cons (concat "\\<\\(" web-mode-asp-constants "\\)\\>")
+         '(0 'web-mode-constant-face))
+   '("\\(Class\\|new\\) \\([[:alnum:]_]+\\)" 2 'web-mode-type-face)
+   '("Const \\([[:alnum:]_]+\\)" 1 'web-mode-constant-face)
+   '("\\<dim\\>"
+     (0 'web-mode-keyword-face)
+     ("[[:alnum:]_]+" nil nil (0 'web-mode-variable-name-face)))
+   '("\\<\\(public\\|private\\|sub\\|function\\)\\> \\([[:alnum:]_]+\\)[ ]*("
+     2 'web-mode-function-name-face)
+   '("\\<\\(public\\|private\\|dim\\)\\> \\([[:alnum:]_]+\\)"
+     2 'web-mode-variable-name-face)
+   ))
+
+(defvar web-mode-aspx-font-lock-keywords
+  (list
+   '("<%[:=#]?\\|%>" 0 'web-mode-preprocessor-face)
+   (cons (concat "\\<\\(" web-mode-aspx-keywords "\\)\\>") '(0 'web-mode-keyword-face))
+   '("\\<\\([[:alnum:].]+\\)[ ]+[[:alpha:]]+" 1 'web-mode-type-face)
+   ))
+
+;;Unified Expression Language
+(defvar web-mode-uel-font-lock-keywords
+  (list
+   '("[$#{]{\\|}" 0 'web-mode-preprocessor-face)
+   '("\\([[:alpha:]_]+\\)[ ]?(" 1 'web-mode-function-name-face)
+   '("[[:alpha:]_]" 0 'web-mode-variable-name-face)
+   ))
+
+(defvar web-mode-freemarker-square-font-lock-keywords
+  (list
+   '("\\[/?[#@]\\|/?>\\|/?\\]" 0 'web-mode-preprocessor-face)
+   '("\\[/?[#@]\\([[:alpha:]_.]*\\)" 1 'web-mode-block-control-face)
+   '("#\\(macro\\|function\\) \\([[:alpha:]]+\\)" 2 'web-mode-function-name-face)
+   (cons (concat "\\<\\(" web-mode-freemarker-keywords "\\)\\>") '(1 'web-mode-keyword-face))
+   '("\\<\\([[:alnum:]._]+\\)[ ]?(" 1 'web-mode-function-name-face)
+   '("[[:alpha:]]\\([[:alnum:]_]+\\)?" 0 'web-mode-variable-name-face)
+   ))
+
+(defvar web-mode-freemarker-font-lock-keywords
+  (list
+   '("</?[#@]\\|/?>\\|/?>" 0 'web-mode-preprocessor-face)
+   '("</?[#@]\\([[:alpha:]_.]*\\)" 1 'web-mode-block-control-face)
+   '("#\\(macro\\|function\\) \\([[:alpha:]]+\\)" 2 'web-mode-function-name-face)
+   (cons (concat "\\<\\(" web-mode-freemarker-keywords "\\)\\>") '(1 'web-mode-keyword-face))
+   '("\\<\\([[:alnum:]._]+\\)[ ]?(" 1 'web-mode-function-name-face)
+   '("[[:alpha:]]\\([[:alnum:]_]+\\)?" 0 'web-mode-variable-name-face)
+   ))
+
+;;TODO : definir web-mode-block-attr-name-face et web-mode-block-attr-name-face
+(defvar web-mode-jsp-tag-font-lock-keywords
+  (list
+   '("</?\\|/?>" 0 'web-mode-preprocessor-face)
+   '("</?\\([[:alpha:]]+:[[:alpha:]]+\\)" 1 'web-mode-block-control-face)
+   '("\\<\\([[:alpha:]]+=\\)\\(\"[^\"]*\"\\)"
+     (1 'web-mode-block-attr-name-face t t)
+     (2 'web-mode-block-attr-value-face t t))
+   ))
+
+(defvar web-mode-jsp-font-lock-keywords
+  (list
+   '("-?%>\\|<%\\(!\\|=\\|#=\\)?" 0 'web-mode-preprocessor-face)
+   '("\\(throws\\|new\\|extends\\)[ ]+\\([[:alnum:].]+\\)" 2 'web-mode-type-face)
+   (cons (concat "\\<\\(" web-mode-jsp-keywords "\\)\\>") '(0 'web-mode-keyword-face))
+   '("\\<\\([[:alnum:]._]+\\)[ ]?(" 1 'web-mode-function-name-face)
+   '("@\\(\\sw*\\)" 1 'web-mode-variable-name-face)
+   '("\\<\\([[:alnum:].]+\\)[ ]+[{[:alpha:]]+" 1 'web-mode-type-face)
+   ))
+
+(defvar web-mode-directive-font-lock-keywords
+  (list
+   '("<%@\\|%>" 0 'web-mode-preprocessor-face)
+   '("<%@[ ]*\\([[:alpha:]]+\\)[ ]+" 1 'web-mode-block-control-face)
+   '("\\<\\([[:alpha:]]+=\\)\\(\"[^\"]*\"\\)"
+     (1 'web-mode-block-attr-name-face t t)
+     (2 'web-mode-block-attr-value-face t t))
+   ))
+
+(defvar web-mode-erb-font-lock-keywords
+  (list
+   '("-?%>\\|^%\\|<%[=-]?" 0 'web-mode-preprocessor-face)
+   '("\\(:[[:alnum:]_]+\\)" 1 'web-mode-symbol-face)
+   '("\\([[:alnum:]_]+:\\)[ ]+" 1 'web-mode-symbol-face)
+   (cons (concat "\\<\\(" web-mode-erb-builtins "\\)\\>")
+         '(0 'web-mode-builtin-face))
+   (cons (concat "\\<\\(" web-mode-erb-keywords "\\)\\>")
+         '(0 'web-mode-keyword-face))
+   '("\\<\\(self\\|true\\|false\\|nil\\)\\>" 0 'web-mode-variable-name-face)
+   '("[@$]@?\\([[:alnum:]_]+\\)" 0 'web-mode-variable-name-face)
+   '("class[ ]+\\([[:alnum:]_]+\\)" 1 'web-mode-type-face)
+   '("def[ ]+\\([[:alnum:]_]+\\)" 1 'web-mode-function-name-face)
+   '("\\(?:\\_<\\|::\\)\\([A-Z]+[[:alnum:]_]+\\)"
+     1 (unless (eq ?\( (char-after)) 'web-mode-type-face))
+   '("/[^/]+/" 0 'web-mode-string-face)
+   ))
+
+(defvar web-mode-python-font-lock-keywords
+  (list
+   '("<\\?\\|\\?>" 0 'web-mode-preprocessor-face)
+   (cons (concat "\\<\\(" web-mode-python-keywords "\\)\\>") '(0 'web-mode-keyword-face))
+   ))
+
+(defvar web-mode-php-font-lock-keywords
+  (list
+   '("<\\?\\(php\\|=\\)?\\|\\?>" 0 'web-mode-preprocessor-face)
+   (cons (concat "\\<\\(" web-mode-php-keywords "\\)\\>") '(0 'web-mode-keyword-face))
+   (cons (concat "(\\<\\(" web-mode-php-types "\\)\\>") '(1 'web-mode-type-face))
+   (cons (concat "\\<\\(" web-mode-php-constants "\\)\\>") '(0 'web-mode-constant-face))
+   '("\\<\\(\\sw+\\)[ ]?(" 1 'web-mode-function-name-face)
+   '("[[:alnum:]_][ ]?::[ ]?\\([[:alnum:]_]+\\)" 1 'web-mode-constant-face)
+   '("->[ ]?\\([[:alnum:]_]+\\)" 1 'web-mode-variable-name-face)
+   '("\\<\\([[:alnum:]_]+\\)[ ]?::" 1 'web-mode-type-face)
+   '("\\<\\(instanceof\\|class\\|extends\\|new\\)[ ]+\\([[:alnum:]_]+\\)" 2 'web-mode-type-face)
+   '("\\<\\([$]\\)\\([[:alnum:]_]*\\)" (1 nil) (2 'web-mode-variable-name-face))
+   ))
+
+(defvar web-mode-blade-font-lock-keywords
+  (append
+   (list
+    '("{{\\|}}" 0 'web-mode-preprocessor-face)
+    '("\\(@\\)\\([[:alpha:]_]+\\)"
+      (1 'web-mode-preprocessor-face)
+      (2 'web-mode-block-control-face)))
+   web-mode-php-font-lock-keywords))
+
+(defvar web-mode-syntax-table
+  (let ((table (make-syntax-table)))
+    (modify-syntax-entry ?_ "w" table)
+    table)
+  "Syntax table in use in web-mode buffers.")
+
+(defvar web-mode-map
+  (let ((map (make-sparse-keymap)))
+
+    (define-key map [menu-bar wm] (cons "Web-Mode" (make-sparse-keymap)))
+    (define-key map [menu-bar wm blk] (cons "Block" (make-sparse-keymap)))
+    (define-key map [menu-bar wm tag] (cons "Html Tag" (make-sparse-keymap)))
+    (define-key map [menu-bar wm elt] (cons "Html Element" (make-sparse-keymap)))
+
+    (define-key map [menu-bar wm sep-1] '(menu-item "--"))
+    (define-key map [menu-bar wm blk blk-sel] '(menu-item "Select" web-mode-block-select))
+    (define-key map [menu-bar wm blk blk-kill] '(menu-item "Kill" web-mode-block-kill))
+    (define-key map [menu-bar wm blk blk-next] '(menu-item "Next" web-mode-block-next))
+    (define-key map [menu-bar wm blk blk-prev] '(menu-item "Previous" web-mode-block-previous))
+    (define-key map [menu-bar wm blk blk-end] '(menu-item "End" web-mode-block-beginning))
+    (define-key map [menu-bar wm blk blk-beg] '(menu-item "Beginning" web-mode-block-beginning))
+    (define-key map [menu-bar wm tag tag-sel] '(menu-item "Select" web-mode-tag-select))
+    (define-key map [menu-bar wm tag tag-match] '(menu-item "Match" web-mode-tag-match))
+    (define-key map [menu-bar wm tag tag-next] '(menu-item "Next" web-mode-tag-next))
+    (define-key map [menu-bar wm tag tag-prev] '(menu-item "Previous" web-mode-tag-previous))
+    (define-key map [menu-bar wm tag tag-end] '(menu-item "End" web-mode-tag-beginning))
+    (define-key map [menu-bar wm tag tag-beg] '(menu-item "Beginning" web-mode-tag-beginning))
+    (define-key map [menu-bar wm elt elt-in] '(menu-item "Inner Content" web-mode-element-content-select))
+    (define-key map [menu-bar wm elt elt-parent] '(menu-item "Parent" web-mode-element-parent))
+    (define-key map [menu-bar wm elt elt-sel] '(menu-item "Select" web-mode-element-select))
+    (define-key map [menu-bar wm elt elt-ren] '(menu-item "Rename" web-mode-element-rename))
+    (define-key map [menu-bar wm elt elt-dup] '(menu-item "Clone" web-mode-element-clone))
+    (define-key map [menu-bar wm elt elt-close] '(menu-item "Close" web-mode-element-close))
+    (define-key map [menu-bar wm elt elt-trav] '(menu-item "Traverse DOM" web-mode-element-traverse))
+    (define-key map [menu-bar wm elt elt-child] '(menu-item "Child" web-mode-element-child))
+    (define-key map [menu-bar wm elt elt-del] '(menu-item "Kill" web-mode-element-kill))
+    (define-key map [menu-bar wm elt elt-next] '(menu-item "Next" web-mode-element-next))
+    (define-key map [menu-bar wm elt elt-prev] '(menu-item "Previous" web-mode-element-previous))
+    (define-key map [menu-bar wm elt elt-end] '(menu-item "End" web-mode-element-end))
+    (define-key map [menu-bar wm elt elt-beg] '(menu-item "Beginning" web-mode-element-beginning))
+    (define-key map [menu-bar wm err] '(menu-item "Show error(s)" web-mode-errors-show))
+    (define-key map [menu-bar wm fold] '(menu-item "Fold/Unfold" web-mode-fold-or-unfold))
+    (define-key map [menu-bar wm indent] '(menu-item "Indent buffer" web-mode-buffer-indent))
+    (define-key map [menu-bar wm nav] '(menu-item "Tag/Block navigation" web-mode-tag-match))
+    (define-key map [menu-bar wm expand] '(menu-item "Mark and Expand" web-mode-mark-and-expand))
+    (define-key map [menu-bar wm space] '(menu-item "Toggle whitespaces" web-mode-whitespaces-show))
+    (define-key map [menu-bar wm xpath] '(menu-item "XPath" web-mode-xpath))
+    (define-key map [menu-bar wm snippet] '(menu-item "Insert snippet" web-mode-snippet-insert))
+    (define-key map [menu-bar wm entities] '(menu-item "Replace HTML entities" web-mode-entities-replace))
+
+    (define-key map (kbd "C-;")       'web-mode-comment-or-uncomment)
+    (define-key map (kbd "M-;")       'web-mode-comment-or-uncomment)
+
+    (define-key map (kbd "C-c C-d")   'web-mode-errors-show)
+    (define-key map (kbd "C-c C-f")   'web-mode-fold-or-unfold)
+    (define-key map (kbd "C-c C-i")   'web-mode-buffer-indent)
+    (define-key map (kbd "C-c C-m")   'web-mode-mark-and-expand)
+    (define-key map (kbd "C-c C-n")   'web-mode-tag-match)
+    (define-key map (kbd "C-c C-r")   'web-mode-entities-replace)
+    (define-key map (kbd "C-c C-s")   'web-mode-snippet-insert)
+    (define-key map (kbd "C-c C-x")   'web-mode-xpath)
+    (define-key map (kbd "C-c C-w")   'web-mode-whitespaces-show)
+
+    (define-key map (kbd "C-c /")     'web-mode-element-close)
+    (define-key map (kbd "C-c <")     'web-mode-element-beginning)
+    (define-key map (kbd "C-c >")     'web-mode-element-end)
+
+    (define-key map (kbd "C-c C-b b") 'web-mode-block-beginning)
+    (define-key map (kbd "C-c C-b e") 'web-mode-block-end)
+    (define-key map (kbd "C-c C-b k") 'web-mode-block-kill)
+    (define-key map (kbd "C-c C-b n") 'web-mode-block-next)
+    (define-key map (kbd "C-c C-b p") 'web-mode-block-previous)
+    (define-key map (kbd "C-c C-b s") 'web-mode-block-select)
+
+    (define-key map (kbd "C-c C-e b") 'web-mode-element-beginning)
+    (define-key map (kbd "C-c C-e c") 'web-mode-element-clone)
+    (define-key map (kbd "C-c C-e d") 'web-mode-element-child)
+    (define-key map (kbd "C-c C-e e") 'web-mode-element-end)
+    (define-key map (kbd "C-c C-e i") 'web-mode-element-content-select)
+    (define-key map (kbd "C-c C-e k") 'web-mode-element-kill)
+    (define-key map (kbd "C-c C-e n") 'web-mode-element-next)
+    (define-key map (kbd "C-c C-e p") 'web-mode-element-previous)
+    (define-key map (kbd "C-c C-e r") 'web-mode-element-rename)
+    (define-key map (kbd "C-c C-e s") 'web-mode-element-select)
+    (define-key map (kbd "C-c C-e t") 'web-mode-element-traverse)
+    (define-key map (kbd "C-c C-e u") 'web-mode-element-parent)
+
+    (define-key map (kbd "C-c C-t b") 'web-mode-tag-beginning)
+    (define-key map (kbd "C-c C-t e") 'web-mode-tag-end)
+    (define-key map (kbd "C-c C-t m") 'web-mode-tag-match)
+    (define-key map (kbd "C-c C-t n") 'web-mode-tag-next)
+    (define-key map (kbd "C-c C-t p") 'web-mode-tag-previous)
+    (define-key map (kbd "C-c C-t s") 'web-mode-tag-select)
+
+    ;; compatibility with nxml
+    (define-key map (kbd "M-C-u")     'web-mode-element-parent)
+    (define-key map (kbd "M-C-d")     'web-mode-element-child)
+    (define-key map (kbd "M-C-n")     'web-mode-element-next)
+    (define-key map (kbd "M-C-p")     'web-mode-element-previous)
+
+    map)
+  "Keymap for `web-mode'.")
+
+;;--- compatibility
+
+(eval-and-compile
+
+  (defalias 'web-mode-prog-mode
+    (if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode))
+
+  (if (fboundp 'with-silent-modifications)
+      (defalias 'web-mode-with-silent-modifications 'with-silent-modifications)
+    (defmacro web-mode-with-silent-modifications (&rest body)
+      "For compatibility with Emacs pre 23.3"
+      `(let ((old-modified-p (buffer-modified-p))
+             (inhibit-modification-hooks t)
+             (buffer-undo-list t))
+         (unwind-protect
+             ,@body
+           (set-buffer-modified-p old-modified-p)))))
+
+  );eval-and-compile
+
+;;;###autoload
+(define-derived-mode web-mode web-mode-prog-mode "Web"
+  "Major mode for editing web templates."
+
+  (make-local-variable 'after-change-functions)
+  (make-local-variable 'font-lock-fontify-buffer-function)
+  (make-local-variable 'font-lock-keywords)
+  (make-local-variable 'font-lock-multiline)
+  (make-local-variable 'font-lock-unfontify-buffer-function)
+;;  (make-local-variable 'forward-sexp-function)
+  (make-local-variable 'imenu-case-fold-search)
+  (make-local-variable 'imenu-create-index-function)
+  (make-local-variable 'imenu-generic-expression)
+  (make-local-variable 'indent-line-function)
+;;  (make-local-variable 'indent-tabs-mode)
+;;  (make-local-variable 'require-final-newline)
+
+  (make-local-variable 'web-mode-buffer-highlighted)
+  (make-local-variable 'web-mode-comment-style)
+  (make-local-variable 'web-mode-content-type)
+  (make-local-variable 'web-mode-display-table)
+  (make-local-variable 'web-mode-engine)
+  (make-local-variable 'web-mode-block-regexps)
+  (make-local-variable 'web-mode-engine-file-regexps)
+  (make-local-variable 'web-mode-expand-initial-pos)
+  (make-local-variable 'web-mode-expand-previous-state)
+  (make-local-variable 'web-mode-has-any-large-block)
+  (make-local-variable 'web-mode-has-any-large-part)
+  (make-local-variable 'web-mode-hl-line-mode-flag)
+  (make-local-variable 'web-mode-indent-style)
+  (make-local-variable 'web-mode-is-narrowed)
+  (make-local-variable 'web-mode-block-regexp)
+  (make-local-variable 'web-mode-time)
+
+  (if (and (fboundp 'global-hl-line-mode)
+           global-hl-line-mode)
+      (setq web-mode-hl-line-mode-flag t))
+
+  (setq fill-paragraph-function 'web-mode-fill-paragraph
+        font-lock-fontify-buffer-function 'web-mode-scan-buffer
+;;        forward-sexp-function 'web-mode-forward-sexp
+        ;;          font-lock-keywords-only t
+        font-lock-unfontify-buffer-function 'web-mode-scan-buffer
+        imenu-case-fold-search t
+        imenu-create-index-function 'web-mode-imenu-index
+        indent-line-function 'web-mode-indent-line
+;;        indent-tabs-mode nil
+;;        require-final-newline nil
+        )
+
+  (remove-hook 'after-change-functions 'font-lock-after-change-function t)
+
+  (add-hook 'after-change-functions 'web-mode-on-after-change t t)
+
+  (add-hook 'after-save-hook
+            '(lambda ()
+               (when web-mode-is-scratch
+                 (web-mode-guess-engine-and-content-type)
+                 (web-mode-scan-buffer)
+;;                 (message "-->%S" (buffer-file-name))
+                 )
+               nil)
+            t t)
+
+  (cond
+   ((boundp 'yas-after-exit-snippet-hook)
+    (add-hook 'yas-after-exit-snippet-hook
+              '(lambda () (web-mode-buffer-refresh))
+              t t))
+   ((boundp 'yas/after-exit-snippet-hook)
+    (add-hook 'yas/after-exit-snippet-hook
+              '(lambda () (web-mode-buffer-refresh))
+              t t))
+   )
+
+  (when web-mode-enable-whitespaces
+    (web-mode-whitespaces-on))
+
+  (web-mode-guess-engine-and-content-type)
+  (web-mode-scan-buffer)
+
+  )
+
+(defun web-mode-forward-sexp (&optional arg)
+  "Move forward."
+  (interactive "p")
+  (unless arg (setq arg 1))
+  (cond
+   ((> arg 0)
+    (while
+        (progn
+          (web-mode-tag-next)
+          (> (setq arg (1- arg)) 0))))
+   ((< arg 0)
+    (while
+        (progn
+          (web-mode-tag-previous)
+          (< (setq arg (1+ arg)) 0))))
+   ))
+
+(defun web-mode-set-engine (engine)
+  "set engine"
+  (interactive
+   (list (completing-read
+          "Engine: "
+          (let (engines elt)
+            (dolist (elt web-mode-engines)
+              (setq engines (append engines (list (car elt)))))
+            engines))))
+  (setq web-mode-content-type "html"
+        web-mode-engine engine)
+  (web-mode-on-engine-setted)
+  (web-mode-scan-buffer)
+  )
+
+(defun web-mode-on-engine-setted ()
+  "engine setted"
+  (when (string= web-mode-engine "razor")
+    (setq web-mode-enable-block-face t))
+  (cond
+   ((member web-mode-content-type '("css" "javascript" "json"))
+    (setq web-mode-has-any-large-part t))
+   ((member web-mode-content-type '("php"))
+    (setq web-mode-has-any-large-block nil)))
+  (setq web-mode-electric-chars nil)
+  (when (string= web-mode-content-type "html")
+    (unless (string= web-mode-engine "none")
+      (setq web-mode-active-block-regexp
+            (cdr (assoc web-mode-engine web-mode-active-block-regexps)))
+      (setq web-mode-close-block-regexp
+            (cdr (assoc web-mode-engine web-mode-close-block-regexps)))
+      (setq web-mode-engine-control-matcher
+            (intern-soft (concat "web-mode-match-" web-mode-engine "-block")))
+      )
+    (setq web-mode-electric-chars
+          (append '(?\<)
+                  (cdr (assoc web-mode-engine web-mode-block-electric-chars)))
+          )
+    );when
+
+    (setq elt (assoc web-mode-engine web-mode-block-regexps))
+    (if elt
+        (setq web-mode-block-regexp (cdr elt))
+      (setq web-mode-engine "none")
+      )
+
+    ;;(message "buffer=%S engine=%S type=%S regexp=%S"
+    ;;          buff-name web-mode-engine web-mode-content-type web-mode-block-regexp)
+
+    ;;  (message "%S\n%S\n%S\n%S" web-mode-active-block-regexp web-mode-close-block-regexp web-mode-engine-control-matcher web-mode-electric-chars)
+
+  )
+
+(defun web-mode-guess-engine-and-content-type ()
+  "Try to guess the server engine and the content type."
+  (let (buff-name elt found)
+    (setq buff-name (buffer-file-name))
+    (unless buff-name (setq buff-name (buffer-name)))
+    (setq web-mode-is-scratch (string= buff-name "*scratch*"))
+    (setq web-mode-content-type nil)
+    (when (boundp 'web-mode-content-types-alist)
+      (setq found nil)
+      (dolist (elt web-mode-content-types-alist)
+        (when (and (not found) (string-match-p (cdr elt) buff-name))
+          (setq web-mode-content-type (car elt)
+                found t))
+        )
+      )
+    (unless web-mode-content-type
+      (setq found nil)
+      (dolist (elt web-mode-content-types)
+        (when (and (not found) (string-match-p (cdr elt) buff-name))
+          (setq web-mode-content-type (car elt)
+                found t))
+        )
+      )
+    (when (boundp 'web-mode-engines-alist)
+      (setq found nil)
+      (dolist (elt web-mode-engines-alist)
+        (when (string-match-p (cdr elt) buff-name)
+          (setq web-mode-engine (car elt)))
+        )
+      )
+    (unless web-mode-engine
+      (setq found nil)
+      (dolist (elt web-mode-engine-file-regexps)
+        (when (and (not found) (string-match-p (cdr elt) buff-name))
+          (setq web-mode-engine (car elt)
+                found t))
+        )
+      )
+    (when web-mode-engine
+      (setq found nil)
+      (dolist (elt web-mode-engines)
+        (when (and (not found) (member web-mode-engine (cdr elt)))
+          (setq web-mode-engine (car elt)
+                found t))
+        )
+      )
+    (web-mode-on-engine-setted)
+    ))
+
+(defun web-mode-imenu-index ()
+  "Return a table of contents."
+  (let (toc-index)
+    (save-excursion
+      (goto-char (point-min))
+      (while (re-search-forward "<h\\([1-9]\\)\\([^>]*\\)>\\([^<]*\\)" nil t)
+	(setq toc-index
+	      (cons (cons (concat (make-string
+				   (* 2 (1- (string-to-number (match-string 1))))
+				   ?\s)
+				  (match-string 3))
+			  (line-beginning-position))
+		    toc-index))))
+    (nreverse toc-index)))
+
+(defun web-mode-scan-buffer ()
+  "Scan entine buffer."
+  (interactive)
+  (web-mode-scan-region (point-min) (point-max)))
+
+(defun web-mode-scan-region (beg end &optional content-type)
+  "Identify code blocks (client/server) and syntactic symbols (strings/comments)."
+  (interactive)
+  (web-mode-trace "scanning region")
+;;  (message "scanning buffer from %d to %d" beg end)
+  (web-mode-with-silent-modifications
+   (save-excursion
+     (save-restriction
+       (save-match-data
+         (let ((inhibit-modification-hooks t)
+               (inhibit-point-motion-hooks t)
+               (inhibit-quit t))
+           (setq beg (if web-mode-is-narrowed 1 beg))
+
+           (cond
+
+            ((member web-mode-content-type '("javascript" "json" "css"))
+             (remove-text-properties beg end web-mode-text-properties2)
+             (web-mode-scan-part beg end web-mode-content-type))
+
+            ((string= web-mode-engine "none")
+             (remove-text-properties beg end web-mode-text-properties2)
+             (web-mode-scan-parts beg end)
+             (web-mode-trace "parts scanned")
+             )
+
+            ((and content-type (member content-type '("css")))
+             (remove-text-properties beg end web-mode-text-properties2)
+             (web-mode-mark-blocks beg end)
+             (web-mode-scan-part beg end "css")
+             (web-mode-scan-blocks beg end)
+             )
+
+            ((and content-type (member content-type '("asp")))
+             (remove-text-properties beg end '(block-token nil font nil))
+             (web-mode-scan-block beg end)
+             )
+
+            (t
+             (remove-text-properties beg end web-mode-text-properties)
+             (web-mode-mark-blocks beg end)
+             (web-mode-trace "blocks marked")
+             (web-mode-scan-parts beg end)
+             (web-mode-trace "parts scanned")
+             (web-mode-scan-blocks beg end)
+             (web-mode-trace "blocks scanned")
+             (when (string= web-mode-engine "django")
+               (web-mode-scan-django-extra-comments beg end)
+               (web-mode-trace "extra")
+               );when
+             )
+
+            );cond
+
+           (if web-mode-enable-whitespaces
+               (web-mode-scan-whitespaces beg end))
+           ))))))
+
+(defun web-mode-mark-blocks (beg end)
+  "Identifies blocks (with block-side, block-beg, block-end text properties)."
+  (save-excursion
+
+    (let ((i 0)
+          open close closing-string start sub1 sub2 sub3 pos tagopen l tmp)
+
+      (goto-char beg)
+
+      ;;      (message "%S: %Sx%S" (point) beg end)
+      ;;      (message "regexp=%S" web-mode-block-regexp)
+      (while (and (< i 1200)
+                  (> end (point))
+                  (re-search-forward web-mode-block-regexp end t))
+
+        (setq i (1+ i)
+              closing-string nil
+              close nil
+              tagopen (match-string 0)
+              open (match-beginning 0)
+              pos nil)
+
+        (when (member (string-to-char tagopen) '(?\s ?\t))
+          (setq l (length tagopen))
+          (setq tagopen (replace-regexp-in-string "\\`[ \t]*" "" tagopen))
+          (setq open (+ open (- l (length tagopen))))
+          )
+
+        (setq sub1 (substring tagopen 0 1)
+              sub2 (substring tagopen 0 2))
+
+        (cond
+
+         ((string= web-mode-engine "php")
+          (unless (looking-at-p "xml ")
+            (setq closing-string '("<\\?". "\\?>"))
+            )
+          );php
+
+         ((string= web-mode-engine "django")
+          (cond
+           ((string= sub2 "{{")
+            (setq closing-string '("{{" . "}}")))
+;;            (setq closing-string "}}"))
+           ((string= sub2 "{%")
+            (setq closing-string "%}"))
+           (t
+            (setq closing-string "#}"))
+           )
+          );django
+
+         ((string= web-mode-engine "ctemplate")
+          (setq closing-string "}}")
+          );ctemplate
+
+         ((or (string= web-mode-engine "asp")
+              (string= web-mode-engine "aspx"))
+          (setq closing-string "%>")
+          );asp
+
+         ((string= web-mode-engine "blade")
+          (cond
+           ((string= sub2 "{{")
+            (setq closing-string "}}"))
+           ((string= sub1 "@")
+            (setq closing-string "EOL"))
+           )
+          );blade
+
+         ((string= web-mode-engine "smarty")
+          (cond
+           ((string= sub2 "{*")
+            (setq closing-string "*}"))
+           ((string= sub2 "{#")
+            (setq closing-string "#}"))
+           (t
+            (setq closing-string "}"))
+           )
+          );smarty
+
+         ((string= web-mode-engine "dust")
+          (cond
+           ((string= sub2 "{!")
+            (setq closing-string "!}"))
+           (t
+            (setq closing-string "}")
+            )
+           )
+          );dust
+
+         ((string= web-mode-engine "closure")
+          (cond
+           ((string= sub2 "//")
+            (setq closing-string "EOL")
+            )
+           ((string= sub2 "/*")
+            (setq closing-string "*/")
+            )
+           (t
+            (setq closing-string "}")
+            )
+           )
+          );closure
+
+         ((string= web-mode-engine "ctemplate")
+          (cond
+           ((string= sub3 "{{{")
+            (setq closing-string "}}}"))
+           (t
+            (setq closing-string "}}"))
+           )
+          );ctemplate
+
+         ((string= web-mode-engine "go")
+          (setq closing-string "}}")
+          );go
+
+         ((string= web-mode-engine "erb")
+          (cond
+           ((string= sub2 "<%")
+            (setq closing-string "%>"))
+           (t
+            (setq closing-string "EOL"))
+           )
+          );erb
+
+         ((string= web-mode-engine "jsp")
+          (cond
+           ((string= sub2 "<%")
+            (setq closing-string "%>"))
+           ((string= sub2 "${")
+            (setq closing-string "}"))
+           (t
+            (setq closing-string ">"))
+           )
+          );jsp
+
+         ((string= web-mode-engine "underscore")
+          (cond
+           (t
+            (setq closing-string "%>"))
+           )
+          );underscore
+
+         ((string= web-mode-engine "template-toolkit")
+          (cond
+           ((string= sub2 "[#")
+            (setq closing-string "#]"))
+           (t
+            (setq closing-string "%]"))
+           )
+          );underscore
+
+         ((string= web-mode-engine "freemarker")
+          (cond
+           ((string= sub1 "<")
+            (setq closing-string ">"))
+           ((string= sub1 "[")
+            (setq closing-string "]"))
+           (t
+            (setq closing-string "}"))
+           )
+          );freemarker
+
+         ((string= web-mode-engine "velocity")
+          (cond
+           ((string= sub2 "##")
+            (setq closing-string "EOL"))
+           ((string= sub2 "#*")
+            (setq closing-string "*#"))
+           (t
+            (setq closing-string "EOV"))
+           )
+          );velocity
+
+         ((string= web-mode-engine "razor")
+          (cond
+           ((string= sub2 "@@")
+            (forward-char 2)
+            (setq closing-string nil))
+           ((string= sub2 "@*")
+            (setq closing-string "*@"))
+           ((string= sub1 "@")
+            (setq closing-string "EOR"))
+           ((string= sub1 "}")
+            (setq closing-string "EOR"))
+           )
+          );razor
+
+         ((string= web-mode-engine "python")
+          (unless (looking-at-p "xml ")
+            (setq closing-string "?>"))
+          );python
+
+         );cond
+
+        (when closing-string
+
+          (cond
+
+           ((listp closing-string)
+            (if (web-mode-rsf-balanced (car closing-string) (cdr closing-string) end t)
+                (progn
+                  (setq close (match-end 0)
+                        pos (point))
+;;                  (message "close=%S pos=%S" close pos)
+                  )
+              (when (string= "<?" sub2)
+                (setq close (point-max)
+                      pos (point-max)))
+              )
+            )
+
+           ((and (member web-mode-engine '("closure" "dust" "smarty"))
+                 (string= closing-string "}"))
+            (goto-char open)
+            (setq tmp (web-mode-closing-paren-position (point) (line-end-position)))
+            (if tmp
+                (setq tmp (1+ tmp))
+              (setq tmp (line-end-position)))
+            (goto-char tmp)
+            (setq close (point)
+                  pos (point))
+            )
+
+           ((string= closing-string "EOL")
+            (end-of-line)
+            (setq close (point)
+                  pos (point)))
+
+           ((string= closing-string "EOR")
+            (web-mode-razor-skip-forward open)
+            (setq close (point)
+                  pos (point)))
+
+           ((string= closing-string "EOV")
+            (web-mode-velocity-skip-forward open)
+            (setq close (point)
+                  pos (point)))
+
+           ((search-forward closing-string end t)
+            (setq close (match-end 0)
+                  pos (point)))
+
+           );cond
+
+          (when (and close (>= end pos))
+            ;;(message "pos(%S) : open(%S) close(%S)" pos open close)
+            (add-text-properties open close '(block-side t))
+            (put-text-property open (1+ open) 'block-beg t)
+            (put-text-property (1- close) close 'block-end t)
+            )
+
+          (if pos (goto-char pos))
+
+          );when closing-string
+
+        );while
+
+      (when (>= i 1200)
+        (message "** strange loop (web-mode-mark-blocks) **"))
+
+      )))
+
+(defun web-mode-scan-django-extra-comments (reg-beg reg-end)
+  "Scan extra"
+  (save-excursion
+    (let (beg end)
+      (goto-char reg-beg)
+      (while (and (< (point) reg-end)
+                  (re-search-forward "{% comment %}" reg-end t))
+        ;;        (message "pt=%S" (point))
+        (setq beg (point))
+        (goto-char (1+ (match-beginning 0)))
+        (when (web-mode-match-django-block)
+          (setq end (1- (point)))
+          (remove-text-properties beg end web-mode-text-properties)
+          (add-text-properties beg end '(block-token comment face web-mode-comment-face))
+          )
+        )
+      )))
+
+(defun web-mode-scan-blocks (region-beg region-end)
+  "Fontify blocks. The scan relies on the 'block-beg text property."
+  (let ((i 0)
+        (comment nil)
+        (beg region-beg)
+        (end nil)
+        (continue t))
+    (while continue
+      (setq end nil
+            i (1+ i))
+      (unless (get-text-property beg 'block-beg)
+        (setq beg (web-mode-block-next-position beg)))
+      (when (and beg (< beg region-end))
+        (setq end (web-mode-block-end-position beg)))
+      (cond
+       ((or (null end)
+            (> end region-end)
+            (> i 1200))
+        (setq continue nil)
+        (if (> i 1200) (message "*** invalid loop (web-mode-scan-blocks) ***")))
+       (t
+        (setq end (1+ end))
+        ;;(message "beg=%S end=%S" beg end)
+
+        (when (and (not web-mode-has-any-large-block)
+                   (> (- end beg) web-mode-large-embed-threshold))
+          (message "** large block detected [ %S - %S ] **" beg end)
+          (setq web-mode-has-any-large-block t))
+
+        (web-mode-scan-block beg end)
+        (when (and (member web-mode-engine '("jsp"))
+                   (> (- end beg) 12)
+                   (eq ?\< (char-after beg)))
+          (web-mode-scan-jsp-tag beg end))
+        (setq beg end)
+        )
+       );cond
+      );while
+
+    ))
+
+(defun web-mode-scan-block (beg end)
+  "Fontify a block."
+  (let ((sub1 "") (sub2 "") (sub3 "") regexp props start ms continue fc keywords tag token-type hddeb hdend hdflk)
+
+;;    (remove-text-properties beg end web-mode-text-properties)
+
+    (goto-char beg)
+
+    (setq sub1 (buffer-substring-no-properties beg (+ beg 1))
+          sub2 (buffer-substring-no-properties beg (+ beg 2)))
+    (setq sub3 sub2)
+    (if (>= (point-max) (+ beg 3))
+        (setq sub3 (buffer-substring-no-properties beg (+ beg 3))))
+
+    (cond
+
+     ((string= web-mode-engine "php")
+      (setq regexp "//\\|/\\*\\|\"\\|'\\|<<<['\"]?\\([[:alnum:]]+\\)['\"]?"
+            props '(face nil)
+            keywords web-mode-php-font-lock-keywords)
+      );php
+
+     ((string= web-mode-engine "django")
+      (cond
+       ((string= sub2 "{{")
+        (setq regexp "\"\\|'"
+              props '(face nil)
+              keywords web-mode-django-expr-font-lock-keywords)
+        )
+       ((string= sub2 "{%")
+        (setq regexp "\"\\|'"
+              props '(face nil)
+              keywords web-mode-django-code-font-lock-keywords)
+        )
+       ((string= sub2 "{#")
+        (setq props '(block-token comment face web-mode-comment-face))
+        )
+       )
+      );django
+
+     ((string= web-mode-engine "ctemplate")
+      (cond
+       ((string= sub3 "{{!")
+        (setq props '(block-token comment face web-mode-comment-face)))
+       ((string= sub3 "{{%")
+        (setq regexp "\"\\|'"
+              props '(face nil)
+              keywords web-mode-ctemplate-font-lock-keywords))
+       (t
+        (setq props '(face nil)
+              keywords web-mode-ctemplate-font-lock-keywords))
+       )
+      );ctemplate
+
+     ((string= web-mode-engine "go")
+      (cond
+       ((string= sub3 "{{/")
+        (setq props '(block-token comment face web-mode-comment-face)))
+       ((string= sub2 "{{")
+        (setq regexp "\"\\|'"
+              props '(face nil)
+              keywords web-mode-go-font-lock-keywords))
+       )
+      );go
+
+     ((string= web-mode-engine "razor")
+      (cond
+       ((string= sub2 "@*")
+        (setq props '(block-token comment face web-mode-comment-face)))
+       (t
+        (setq regexp "\"\\|'"
+              props '(face nil)
+              keywords web-mode-razor-font-lock-keywords))
+       )
+      );razor
+
+     ((string= web-mode-engine "python")
+      (setq regexp "\"\\|'\\|#"
+            props '(face nil)
+            keywords web-mode-python-font-lock-keywords)
+      );python
+
+     ((string= web-mode-engine "blade")
+      (cond
+       ((string= sub3 "{{-")
+        (setq props '(block-token comment face web-mode-comment-face)))
+       (t
+        (setq regexp "\"\\|'"
+              props '(face nil)
+              keywords web-mode-blade-font-lock-keywords))
+       )
+      );blade
+
+     ((string= web-mode-engine "velocity")
+      (cond
+       ((member sub2 '("##" "#*"))
+        (setq props '(block-token comment face web-mode-comment-face)))
+       ((string= sub1 "$")
+        (setq regexp "\"\\|'"
+              props '(face nil)
+              keywords web-mode-velocity-font-lock-keywords))
+       ((string= sub1 "#")
+        (setq regexp "\"\\|'"
+              props '(face nil)
+              keywords web-mode-velocity-font-lock-keywords))
+       )
+      );velocity
+
+     ((string= web-mode-engine "jsp")
+      (cond
+       ((string= sub3 "<%-")
+        (setq props '(block-token comment face web-mode-comment-face)))
+       ((string= sub3 "<%@")
+        (setq regexp "/\\*"
+              props '(face nil)
+              keywords web-mode-directive-font-lock-keywords))
+       ((member sub2 '("${" "#{"))
+        (setq regexp "\"\\|'"
+              props '(face nil)
+              keywords web-mode-uel-font-lock-keywords))
+       ((string= sub2 "<%")
+        (setq regexp "//\\|/\\*\\|\"\\|'"
+              props '(face nil)
+              keywords web-mode-jsp-font-lock-keywords))
+       (t
+        (setq props '(face nil)
+              keywords web-mode-jsp-tag-font-lock-keywords)
+        )
+       )
+      );jsp
+
+     ((string= web-mode-engine "freemarker")
+      (cond
+       ((member sub3 '("<#-" "[#-"))
+        (setq props '(block-token comment face web-mode-comment-face))
+        )
+       ((member sub2 '("${" "#{"))
+        (setq regexp "\"\\|'"
+              props '(face nil)
+              keywords web-mode-uel-font-lock-keywords))
+       ((or (member sub2 '("<@" "[@" "<#" "[#"))
+            (member sub3 '("</@" "[/@" "</#" "[/#")))
+        (setq regexp "\""
+              props '(face nil)
+              keywords (if (eq ?\[ (aref sub2 0))
+                           web-mode-freemarker-square-font-lock-keywords
+                         web-mode-freemarker-font-lock-keywords))
+        )
+       (t
+        (setq props '(face nil)
+              keywords web-mode-jsp-tag-font-lock-keywords)
+        )
+       )
+      );freemarker
+
+     ((string= web-mode-engine "erb")
+      (cond
+       ((string= sub3 "<%#")
+        (setq props '(block-token comment face web-mode-comment-face)))
+       (t
+        (setq regexp "\"\\|'\\|#\\|<<[-]?['\"]?\\([[:alnum:]]+\\)['\"]?"
+              props '(face nil)
+              keywords web-mode-erb-font-lock-keywords)
+        )
+       )
+      );erb
+
+     ((string= web-mode-engine "asp")
+      (setq regexp "//\\|/\\*\\|\"\\|'"
+            props '(face nil)
+            keywords web-mode-asp-font-lock-keywords)
+      );asp
+
+
+     ((string= web-mode-engine "template-toolkit")
+      (cond
+       ((string= sub2 "[#")
+        (setq props '(block-token comment face web-mode-comment-face)))
+       (t
+        (setq regexp "#\\|\"\\|'"
+              props '(face nil)
+              keywords web-mode-template-toolkit-font-lock-keywords)
+        )));template-toolkit
+
+     ((string= web-mode-engine "underscore")
+      (setq regexp "/\\*\\|\"\\|'"
+            props '(face nil)
+            keywords web-mode-underscore-font-lock-keywords)
+      );underscore
+
+     ((string= web-mode-engine "aspx")
+      (cond
+       ((string= sub3 "<%-")
+        (setq props '(block-token comment face web-mode-comment-face)))
+       ((string= sub3 "<%@")
+        (setq regexp "/\\*"
+              props '(face nil)
+              keywords web-mode-directive-font-lock-keywords))
+       ((string= sub3 "<%$")
+        (setq regexp "\"\\|'"
+              props '(face nil)
+              keywords web-mode-expression-font-lock-keywords))
+       (t
+        (setq regexp "//\\|/\\*\\|\"\\|'"
+              props '(face nil)
+              keywords web-mode-aspx-font-lock-keywords)
+        )
+       )
+      );aspx
+
+     ((string= web-mode-engine "smarty")
+      (cond
+       ((string= sub2 "{*")
+        (setq props '(block-token comment face web-mode-comment-face))
+        )
+       (t
+        (setq regexp "\"\\|'"
+              props '(face nil)
+              keywords web-mode-smarty-font-lock-keywords)
+        )
+       )
+      );smarty
+
+     ((string= web-mode-engine "dust")
+      (cond
+       ((string= sub2 "{!")
+        (setq props '(block-token comment face web-mode-comment-face))
+        )
+       (t
+        (setq regexp "\"\\|'"
+              props '(face nil)
+              keywords web-mode-dust-font-lock-keywords)
+        )
+       )
+      );dust
+
+     ((string= web-mode-engine "closure")
+      (cond
+       ((member sub2 '("/*" "//"))
+        (setq props '(block-token comment face web-mode-comment-face))
+        )
+       (t
+        (setq regexp "\"\\|'"
+              props '(face nil)
+              keywords web-mode-closure-font-lock-keywords)
+        )
+       )
+      );closure
+
+     )
+
+    (add-text-properties beg end props)
+
+    (when keywords (web-mode-fontify-region beg end keywords))
+
+    (when regexp
+      (setq token-type "string")
+      (goto-char beg)
+      (while (re-search-forward regexp end t)
+        (setq start (match-beginning 0)
+              ms (match-string 0)
+              continue t)
+        (setq fc (aref ms 0))
+        (cond
+
+         ((and (string= web-mode-engine "asp")
+               (eq fc ?\'))
+          (setq props '(block-token comment face web-mode-block-comment-face)
+                token-type "comment")
+          (goto-char (if (< end (line-end-position)) end (line-end-position)))
+          )
+
+         ((eq fc ?\')
+          (setq props '(block-token string face web-mode-block-string-face))
+          (while (and continue (search-forward "'" end t))
+            (setq continue (eq ?\\ (char-before (1- (point)))))
+            )
+          )
+
+         ((eq fc ?\")
+          (setq props '(block-token string face web-mode-block-string-face))
+          (while (and continue (search-forward "\"" end t))
+            (setq continue (eq ?\\ (char-before (1- (point)))))
+            )
+          )
+
+         ((string= ms "//")
+          (setq props '(block-token comment face web-mode-block-comment-face)
+                token-type "comment")
+          (goto-char (if (< end (line-end-position)) end (line-end-position)))
+          )
+
+         ((eq fc ?\#)
+          (setq props '(block-token comment face web-mode-block-comment-face)
+                token-type "comment")
+          (goto-char (if (< end (line-end-position)) end (line-end-position)))
+          )
+
+
+         ((string= ms "/*")
+          (setq props '(block-token comment face web-mode-block-comment-face)
+                token-type "comment")
+          (search-forward "*/" end t)
+          )
+
+         ((eq fc ?\<)
+          (when (and web-mode-enable-heredoc-fontification
+                     (string-match-p "JS\\|JAVASCRIPT\\|HTM\\|CSS" (match-string 1)))
+            (setq hddeb (1+ (point))
+                  hdflk (if (string-match-p "HTM" (match-string 1))
+                            web-mode-html-font-lock-keywords
+                          web-mode-javascript-font-lock-keywords))
+            )
+          ;;          (message "tag=%s pos=%S" (match-string 1) (point))
+          (setq props '(block-token string face web-mode-block-string-face))
+          (re-search-forward (concat "^[ ]*" (match-string 1)) end t)
+          (when hddeb (setq hdend (1- (match-beginning 0))))
+          )
+
+         ((and (member web-mode-engine '("python" "erb"))
+               (eq fc ?\#))
+          (setq props '(block-token comment face web-mode-block-comment-face))
+          (goto-char (if (< end (line-end-position)) end (line-end-position)))
+          )
+
+         );;cond
+
+        ;;        (message "elt=%S" (buffer-substring start (point)))
+        (add-text-properties start (point) props)
+
+        (when (and (eq fc ?\")
+                   (member web-mode-engine '("php" "erb"))
+                   (> (- (point) start) 4))
+          (web-mode-interpolate-string start (point))
+          )
+
+        (when hddeb
+          (web-mode-fontify-region hddeb hdend hdflk)
+          (setq hddeb nil))
+
+        (cond
+         ((string= token-type "comment")
+          (if web-mode-enable-comment-keywords
+              (web-mode-interpolate-comment start (point) t))
+          )
+         (t
+          )
+         )
+
+        );while
+
+      );when regexp
+
+    (when web-mode-enable-block-face
+      (font-lock-prepend-text-property beg end
+                                      'face
+                                      'web-mode-block-face))
+    ))
+
+(defun web-mode-scan-jsp-tag (beg end)
+  "Scan a jsp tag to fontify ${ } blocks"
+  (save-excursion
+    (goto-char (+ 4 beg))
+    (setq end (1- end))
+    (while (re-search-forward "${.*}" end t)
+      (web-mode-fontify-region (match-beginning 0) (match-end 0)
+                               web-mode-uel-font-lock-keywords)
+      )
+    ))
+
+(defun web-mode-interpolate-string (beg end)
+  "Interpolate php/erb strings."
+  (save-excursion
+    (goto-char (1+ beg))
+    (setq end (1- end))
+    (cond
+     ((string= web-mode-engine "php")
+      (while (re-search-forward "$[[:alnum:]]+" end t)
+        (put-text-property (match-beginning 0) (match-end 0)
+                           'face nil)
+        (put-text-property (1+ (match-beginning 0)) (match-end 0)
+                           'face 'web-mode-variable-name-face)
+        ))
+     ((string= web-mode-engine "erb")
+      (while (re-search-forward "#{.*}" end t)
+        (put-text-property (match-beginning 0) (match-end 0)
+                           'face 'web-mode-variable-name-face)
+        ))
+     );cond
+    ))
+
+
+(defun web-mode-interpolate-comment (beg end block-side)
+  "Interpolate comment"
+  (save-excursion
+    (let (regexp)
+      (goto-char beg)
+      (setq regexp (concat "\\<\\(" web-mode-comment-keywords "\\)\\>"))
+      (while (re-search-forward regexp end t)
+        (font-lock-prepend-text-property (match-beginning 1) (match-end 1)
+                                         'face
+                                         'web-mode-comment-keyword-face)
+        )
+      )))
+
+;; start-tag, end-tag, tag-name, element (<a>xsx</a>, an element is delimited by tags), void-element
+;; http://www.w3.org/TR/html-markup/syntax.html#syntax-elements
+;;<#include "toto">
+(defun web-mode-scan-parts (beg end)
+  "Scan client side blocks (JavaScript / CSS / HTML Comments) and identifies strings and comments."
+  (save-excursion
+    (let (open limit close ms expr props closing-string start tag tag-name tag-beg tag-end tag-stop element-content-type attrs-end close-found pos markup-face prop-type prop-name)
+
+      (goto-char beg)
+
+      ;; <\\(!--\\|!doctype\\|/?[[:alnum:]]+[:_]?[[:alnum:]]*\\|\?xml\\)
+      ;; <\\(/?[[:alnum:]]+\\|!--\\|!doctype\\|\?xml\\)
+      ;; <[[:alpha:]/!?]
+      (while (web-mode-rsf-client "<\\(/?[[:alnum:]]+\\|!--\\|!doctype\\|\?xml\\)" end t)
+        (setq tag-name (downcase (match-string 1))
+              tag-beg (match-beginning 0)
+              tag-end nil
+              element-content-type nil
+              tag-stop (point)
+              prop-name 'tag-name
+              prop-type 'tag-type
+              open nil
+              limit end
+              close nil
+              pos nil
+              markup-face nil
+              props nil
+              expr nil
+              closing-string nil
+              close-found nil)
+
+        (cond
+         ((string= tag-name "!--")
+          (setq expr "-->"))
+         ((string= tag-name "!doctype")
+          (setq expr ">"))
+         ((string= tag-name "?xml")
+          (setq expr "?>"))
+         (t
+          (setq props '(face web-mode-html-tag-face))
+          (cond
+           ((eq ?\/ (string-to-char tag-name))
+            (setq props (plist-put props prop-name (substring tag-name 1)))
+            (setq props (plist-put props prop-type 'end))
+            (setq expr ">")
+            (setq limit (if (> end (line-end-position)) (line-end-position) end))
+            )
+           ((web-mode-is-void-element tag-name)
+            (setq props (plist-put props prop-name tag-name))
+            (setq props (plist-put props prop-type 'void))
+            (setq expr ">")
+            )
+           (t
+            (setq props (plist-put props prop-name tag-name))
+            (setq props (plist-put props prop-type 'start))
+            (setq expr ">")
+            )
+           );cond
+          );t
+         );cond
+
+        (if (web-mode-sf-client expr limit t)
+            (progn
+              (setq attrs-end (- (point) (length expr))
+                    tag-end (point)
+                    close-found t)
+              (when (eq ?\/ (char-after (- (point) 2)))
+                (setq attrs-end (1- attrs-end)
+                      props (plist-put props prop-type 'void)))
+              );progn
+          (setq attrs-end (line-end-position)
+                tag-end (line-end-position))
+          );if
+
+        (cond
+         ((string= tag-name "script")
+          (setq tag (buffer-substring-no-properties tag-beg tag-end))
+          (cond
+           ((string-match-p " type[ ]*=[ ]*[\"']text/\\(x-handlebars\\|html\\)" tag)
+            (setq element-content-type "html"))
+           ((string-match-p " type[ ]*=[ ]*[\"']application/\\(ld\\+json\\|json\\)" tag)
+            (setq element-content-type "json"))
+           (t
+            (setq element-content-type "javascript"))
+           )
+;;          (message "tag=%S : %S" tag element-content-type)
+          );case script
+         ((string= tag-name "style")
+          (setq element-content-type "css")
+          )
+         )
+
+;;        (message "tag=%S (%S > %S)\n%S" tag-name tag-beg tag-end props)
+        (add-text-properties tag-beg tag-end props)
+        (put-text-property tag-beg (1+ tag-beg) 'tag-beg t)
+        (put-text-property (1- tag-end) tag-end 'tag-end t)
+
+        (cond
+
+         ((or (string= tag-name "!doctype") (string= tag-name "?xml"))
+          (add-text-properties tag-beg tag-end '(tag-name "doctype" tag-type void face web-mode-doctype-face)))
+
+         ((string= tag-name "!--")
+          (add-text-properties tag-beg tag-end '(tag-name "comment" tag-type void part-side t part-token comment face web-mode-comment-face)))
+
+         (close-found
+          (when (and (not (eq ?\/ (aref tag-name 0)))
+                     (> (- attrs-end tag-stop) 1))
+;;            (message "tag-stop=%S attrs-end=%S" tag-stop attrs-end)
+            (web-mode-scan-attrs tag-stop attrs-end)
+            )
+          (cond
+           ((and (string= tag-name "script")
+                 (member element-content-type '("javascript" "json")))
+            (setq closing-string "</script>"))
+           ((string= tag-name "style")
+            (setq closing-string "</style>"))
+           )
+
+          ;; si <script type="document/html"> on ne fait pas la suite
+
+          (when (and closing-string (web-mode-sf-client closing-string end t))
+            (setq open tag-end
+                  close (match-beginning 0))
+            (if (>= (- close open) 3)
+                (web-mode-scan-part open close element-content-type)
+              (remove-text-properties open close web-mode-text-properties2))
+            (goto-char close)
+            ); when
+          ); close-found
+         ); cond tag
+
+        ); while
+
+      )))
+
+;; todo : il serait préférable d'identifier les tokens et ensuite de fontifier
+(defun web-mode-scan-part (part-beg part-end content-type)
+  "Scan client part (e.g. javascript, json, css)."
+  (save-excursion
+    (let (token-re ch-before ch-at ch-next props start continue keywords token-type face)
+
+      (remove-text-properties part-beg part-end web-mode-text-properties2)
+
+      (goto-char part-beg)
+
+      (when (and (not web-mode-has-any-large-part)
+                 (> (- part-end part-beg) web-mode-large-embed-threshold))
+        (message "** large part detected [ %S - %S ] **" part-beg part-end)
+        (setq web-mode-has-any-large-part t))
+
+      (cond
+       ((string= content-type "javascript")
+        (setq token-re "//\\|/\\*\\|\"\\|'"
+              keywords web-mode-javascript-font-lock-keywords
+              props '(part-language javascript part-side t)))
+       ((string= content-type "json")
+        (setq token-re "//\\|/\\*\\|\"\\|'"
+              keywords web-mode-javascript-font-lock-keywords
+              props '(part-language json part-side t)))
+       ((string= content-type "css")
+        (setq token-re "/\\*\\|\"\\|'"
+              props '(part-language css part-side t)))
+       )
+
+      (add-text-properties part-beg part-end props)
+
+      (when keywords
+        (web-mode-fontify-region part-beg part-end keywords))
+
+      (when (string= content-type "css")
+        (web-mode-css-scan-rules part-beg part-end))
+
+      (when token-re
+        (while (and token-re (web-mode-rsf-client token-re part-end t))
+          (setq start (match-beginning 0)
+                props nil
+                continue t)
+          (setq ch-at (char-after start))
+          (setq ch-next (or (char-after (1+ start)) ?\d))
+          (setq ch-before (or (char-before start) ?\d))
+          (setq token-type "string")
+          ;;        (message "beg=%S :%c%c%c" start ch-before ch-at ch-next)
+          (cond
+
+           ((eq ?\' ch-at)
+            (unless (eq ?\\ ch-before)
+              (while (and continue (search-forward "'" part-end t))
+                (setq continue (or (get-text-property (1- (point)) 'block-side)
+                                   (eq ?\\ (char-before (1- (point))))))
+                )
+              (cond
+               ((string= content-type "javascript")
+                (setq props '(part-token string face web-mode-javascript-string-face)))
+               ((string= content-type "css")
+                (setq props '(part-token string face web-mode-css-string-face)))
+               ((string= content-type "json")
+                (setq props '(part-token string face web-mode-json-string-face)))
+               (t
+                (setq props '(part-token string face web-mode-part-string-face)))
+               );cond
+              );unless
+            )
+
+           ((eq ?\" ch-at)
+            (unless (eq ?\\ ch-before)
+              (while (and continue (search-forward "\"" part-end t))
+                (setq continue (or (get-text-property (1- (point)) 'block-side)
+                                   (eq ?\\ (char-before (1- (point))))))
+                )
+              (cond
+               ((string= content-type "json")
+                (if (looking-at-p "[ ]*:")
+                    (cond
+                     ((eq ?\@ (char-after (1+ start)))
+                      (setq props '(part-token string face web-mode-json-context-face))
+                      )
+                     (t
+                      (setq props '(part-token string face web-mode-json-key-face))
+                      )
+                     )
+                  (setq props '(part-token string face web-mode-json-string-face)))
+                )
+               (t
+                (cond
+                 ((string= content-type "javascript")
+                  (setq props '(part-token string face web-mode-javascript-string-face)))
+                 ((string= content-type "css")
+                  (setq props '(part-token string face web-mode-css-string-face)))
+                 (t
+                  (setq props '(part-token string face web-mode-part-string-face)))
+                 );cond
+                );t
+               );cond
+              );unless
+            )
+
+           ((eq ?\/ ch-next)
+            (unless (eq ?\\ ch-before)
+              (setq props '(part-token comment face web-mode-part-comment-face)
+                    token-type "comment")
+              (goto-char (if (< part-end (line-end-position)) part-end (line-end-position)))
+              )
+            )
+
+           ((eq ?\* ch-next)
+            (unless (eq ?\\ ch-before)
+              (setq props '(part-token comment face web-mode-part-comment-face)
+                    token-type "comment")
+              (search-forward "*/" part-end t)
+              )
+            )
+
+           );cond
+
+          (when (>= part-end (point))
+            (if props (add-text-properties start (point) props))
+            (when (and (string= token-type "comment")
+                       web-mode-enable-comment-keywords)
+              (web-mode-interpolate-comment start (point) t))
+            )
+
+          ));while | when token-re
+
+      (when web-mode-enable-part-face
+        (font-lock-append-text-property part-beg part-end
+                                        'web-mode-part-face
+                                        face))
+
+      )))
+
+(defun web-mode-css-scan-rules (part-beg part-end)
+  "Fontify css rule."
+  (save-excursion
+    (goto-char part-beg)
+    (let (rule (continue t) (i 0) at-rule)
+      (while continue
+        (setq i (1+ i))
+        (setq rule (web-mode-css-next-rule part-end))
+;;        (if (< (point) 328) (message "pt=%S" (point)))
+;;        (if (and (< i 6) rule) (message "%S rule=%S (%S)" i rule (point)))
+        (cond
+         ((> i 1000)
+          (message "*** too much css rules ***")
+          (setq continue nil))
+         ((null rule)
+          (setq continue nil)
+          )
+         ((and (setq at-rule (plist-get rule :at-rule))
+               (not (member at-rule '("charset" "font-face" "import")))
+               (plist-get rule :dec-end))
+          (web-mode-css-fontify-rule (plist-get rule :sel-beg)
+                                     (plist-get rule :sel-end)
+                                     nil nil)
+          (web-mode-css-scan-rules (plist-get rule :dec-beg)
+                                   (plist-get rule :dec-end))
+          )
+         (t
+          (web-mode-css-fontify-rule (plist-get rule :sel-beg)
+                                     (plist-get rule :sel-end)
+                                     (plist-get rule :dec-beg)
+                                     (plist-get rule :dec-end))
+          )
+         );cond
+        )
+      )
+    ))
+
+(defun web-mode-css-fontify-rule (sel-beg sel-end dec-beg dec-end)
+  "Fontify css rule."
+  (save-excursion
+    (web-mode-fontify-region sel-beg sel-end
+                             web-mode-selector-font-lock-keywords)
+    (when (and dec-beg dec-end)
+      (web-mode-fontify-region dec-beg dec-end
+                               web-mode-declaration-font-lock-keywords)
+      (goto-char dec-beg)
+      (while (and (not web-mode-disable-css-colorization)
+                  (re-search-forward "#[0-9a-fA-F]\\{6\\}\\|#[0-9a-fA-F]\\{3\\}\\|rgb([ ]*\\([[:digit:]]\\{1,3\\}\\)[ ]*,[ ]*\\([[:digit:]]\\{1,3\\}\\)[ ]*,[ ]*\\([[:digit:]]\\{1,3\\}\\)\\(.*?\\))" dec-end t)
+                  (< (point) dec-end))
+        (web-mode-colorize (match-beginning 0) (match-end 0))
+        )
+      )))
+
+;; css rule = selectors + declaration (properties)
+(defun web-mode-css-next-rule (limit)
+  "next rule"
+  (let (at-rule sel-beg sel-end dec-beg dec-end chunk)
+    (skip-chars-forward "[\n\t ]")
+    (setq sel-beg (point))
+    (when (and (< (point) limit)
+               (web-mode-rsf-client "[{;]" limit t))
+      (setq sel-end (1- (point)))
+      (cond
+       ((eq (char-before) ?\{)
+        (setq dec-beg (point))
+        (setq dec-end (web-mode-closing-paren-position (1- dec-beg) limit))
+        (if dec-end
+            (progn
+              (goto-char dec-end)
+              (forward-char))
+          (setq dec-end limit)
+          (goto-char limit))
+        )
+       (t
+        )
+       );cond
+      (setq chunk (buffer-substring-no-properties sel-beg sel-end))
+      (when (string-match "@\\([[:alpha:]-]+\\)" chunk)
+        (setq at-rule (match-string-no-properties 1 chunk))
+;;        (message "%S at-rule=%S" chunk at-rule)
+        )
+      );when
+    (if (not sel-end)
+        (progn (goto-char limit) nil)
+      (list :at-rule at-rule
+            :sel-beg sel-beg
+            :sel-end sel-end
+            :dec-beg dec-beg
+            :dec-end dec-end)
+      );if
+    ))
+
+(defun web-mode-css-current-rule (pos min max)
+  "current css rule"
+  (save-excursion
+    (let (beg end)
+      (goto-char pos)
+      (if (not (web-mode-sb-client "{" min t))
+          (progn
+            (setq beg min)
+            (if (web-mode-sf-client ";" max t)
+                (setq end (1+ (point)))
+              (setq end max))
+            )
+        (setq beg (point))
+        (setq end (web-mode-closing-paren-position beg max))
+        (if end
+            (setq end (1+ end))
+          (setq end max)
+          )
+;;        (message "%S >>beg%S >>end%S" pos beg end)
+        (if (> pos end)
+
+            ;;selectors
+            (progn
+              (goto-char pos)
+              (if (web-mode-rsb-client "[};]" min t)
+                  (setq beg (1+ (point)))
+                (setq beg min)
+                )
+              (goto-char pos)
+              (if (web-mode-rsf-client "[{;]" max t)
+                  (cond
+                   ((eq (char-before) ?\;)
+                    (setq end (point))
+                    )
+                   (t
+                    (setq end (web-mode-closing-paren-position (1- (point)) max))
+                    (if end
+                        (setq end (1+ end))
+                      (setq end max))
+                    )
+                   );cond
+                (setq end max)
+                )
+              );progn selectors
+
+          ;; declaration
+          (goto-char beg)
+          (if (web-mode-rsb-client "[}{;]" min t)
+              (setq beg (1+ (point)))
+            (setq beg min)
+            )
+          )
+        )
+;;      (message "beg(%S) end(%S)" beg end)
+      (cons beg end)
+      )))
+
+;; http://www.w3.org/TR/html-markup/syntax.html#syntax-attributes
+;; states:
+;; nil(0) space(1) name(2) space-before(3) equal(4) space-after(5) value-uq(6) value-sq(7) value-dq(8)
+(defun web-mode-scan-attrs (beg end)
+  "Scan and fontify html attributes."
+  (save-excursion
+  ;;    (message "beg(%S) end(%S)" beg end)
+    (let (name-beg name-end val-beg val-end (state 0) char pos escaped spaced)
+      (goto-char (1- beg))
+
+      (while (< (point) end)
+        (forward-char)
+        (setq pos (point)
+              char (char-after))
+        (setq spaced (eq ?\s char))
+;;        (setq char (buffer-substring-no-properties pos (1+ pos)))
+
+        (cond
+
+         ((= pos end)
+          (web-mode-propertize-attr state char name-beg name-end val-beg)
+          (setq state 0
+                name-beg nil
+                name-end nil
+                val-beg nil
+                val-end nil)
+          )
+
+         ((get-text-property pos 'block-side)
+          )
+
+         ((and spaced (= state 0))
+          (setq state 1)
+          )
+
+         ((and spaced (member state '(1 3 5)))
+          )
+
+         ((and spaced (= state 2))
+          (setq state 3)
+          )
+
+         ((and spaced (= state 4))
+          (setq state 5)
+          )
+
+         ((and (eq ?\n char) (not (member state '(7 8))))
+          (web-mode-propertize-attr state char name-beg name-end val-beg)
+          (setq state 1
+                name-beg nil
+                name-end nil
+                val-beg nil
+                val-end nil)
+          )
+
+         ((or (and (eq ?\" char) (= state 8) (not escaped))
+              (and (eq ?\' char) (= state 7) (not escaped))
+              (and (member char '(?\s ?\n ?\>)) (= state 6)))
+          (web-mode-propertize-attr state char name-beg name-end val-beg)
+          (setq state (if (= state 6) 1 0)
+                name-beg nil
+                name-end nil
+                val-beg nil
+                val-end nil)
+          )
+
+         ((and (not spaced) (= state 1))
+          (setq state 2)
+          (setq name-beg pos)
+          )
+
+         ((and (eq ?\= char) (member state '(2 3)))
+          (setq name-end pos)
+          (setq state 4)
+          )
+
+         ((and (eq ?\" char) (member state '(4 5)))
+          (setq val-beg pos)
+          (setq state 8)
+          )
+
+         ((and (eq ?\' char) (member state '(4 5)))
+          (setq val-beg pos)
+          (setq state 7)
+          )
+
+         ((member state '(4 5))
+          (setq val-beg pos)
+          (setq state 6)
+          )
+
+         ((= state 1)
+          (setq state 2)
+          )
+
+         );;cond
+
+        ;;        (message "point(%S) end(%S) state(%S) c(%S) name-beg(%S) name-end(%S) val-beg(%S) val-end(%S)" pos end state char name-beg name-end val-beg val-end)
+
+        (setq escaped (eq ?\\ char))
+
+        );;while
+
+      )))
+
+(defun web-mode-propertize-attr (state char name-beg name-end val-beg &optional val-end)
+  "propertize attr."
+  (unless val-end (setq val-end (point)))
+  ;;  (message "point(%S) state(%S) c(%S) name-beg(%S) name-end(%S) val-beg(%S) val-end(%S)" (point) state char name-beg name-end val-beg val-end)
+  (cond
+   ((and (= state 8) (not (eq ?\" char)))
+    )
+   ((and (= state 7) (not (eq ?\' char)))
+    )
+   ((= state 4)
+    )
+   ((null name-beg)
+    )
+   (t
+    (if (or (and (= state 8) (eq ?\" char))
+            (and (= state 7) (eq ?\' char)))
+        (add-text-properties name-beg (1+ (point)) '(part-token attr face web-mode-html-attr-name-face))
+      (add-text-properties name-beg (point) '(part-token attr face web-mode-html-attr-name-face)))
+    (when (and val-beg val-end)
+      (setq val-end (if (eq ?\> char) val-end (1+ val-end)))
+      (add-text-properties val-beg val-end '(face web-mode-html-attr-value-face)))
+    );t
+   );cond
+  )
+
+(defun web-mode-velocity-skip-forward (pos)
+  "find the end of a velocity block."
+  (goto-char pos)
+  (let (continue)
+    (when (eq ?\# (char-after))
+      (forward-char))
+    ;;(message "pt=%S %c" (point) (char-after))
+    (when (member (char-after) '(?\$ ?\@))
+      ;;              (message "pt=%S" (point))
+      (forward-char))
+    (when (member (char-after) '(?\!))
+      ;;              (message "pt=%S" (point))
+      (forward-char))
+    (if (member (char-after) '(?\{))
+        (search-forward "}")
+      (setq continue t)
+      (while continue
+        (skip-chars-forward "a-zA-Z0-9_-")
+        (when (member (char-after) '(?\())
+          (search-forward ")")
+          )
+        (if (member (char-after) '(?\.))
+            (forward-char)
+          (setq continue nil))
+        );while
+      );if
+    ))
+
+(defun web-mode-razor-skip-forward (pos)
+  "find the end of a razor block."
+  (goto-char pos)
+  ;;            (message "pt=%S %c" (point) (char-after))
+  (let (continue)
+    (cond
+     ((looking-at-p "@\\(if\\|for\\|section\\)")
+      (search-forward "{")
+      )
+     ((looking-at-p "@[(}]")
+      (forward-char)
+      (goto-char (web-mode-closing-paren-position (point) (line-end-position)))
+      )
+     (t
+      (forward-char)
+      (setq continue t)
+      (while continue
+        (skip-chars-forward " a-zA-Z0-9_-"); caractère 'espace' pour '} else {'
+        (cond
+         ((eq ?\( (char-after))
+          (search-forward ")")
+          )
+         ((eq ?\. (char-after))
+          (forward-char))
+         ((looking-at-p "[ ]*{")
+          (search-forward "}")
+          )
+         (t
+          (setq continue nil))
+         );cond
+        );while
+      )
+     );cond
+    ))
+
+(defun web-mode-colorize-foreground (color)
+  "Colorize foreground based on background luminance."
+  (let* ((values (x-color-values color))
+	 (r (car values))
+	 (g (cadr values))
+	 (b (car (cdr (cdr values)))))
+    (if (> 128.0 (floor (+ (* .3 r) (* .59 g) (* .11 b)) 256))
+	"white" "black")))
+
+(defun web-mode-colorize (beg end)
+  "Colorize CSS colors."
+  (let (str plist len)
+    (setq str (buffer-substring-no-properties beg end))
+    (setq len (length str))
+    (cond
+     ((string= (substring str 0 1) "#")
+      (setq plist (list :background str
+                        :foreground (web-mode-colorize-foreground str)))
+      (put-text-property beg end 'face plist))
+     ((string= (substring str 0 4) "rgb(")
+      (setq str (format "#%02X%02X%02X"
+                        (string-to-number (match-string-no-properties 1))
+                        (string-to-number (match-string-no-properties 2))
+                        (string-to-number (match-string-no-properties 3))))
+      (setq plist (list :background str
+                        :foreground (web-mode-colorize-foreground str)))
+      (put-text-property beg end 'face plist))
+     );cond
+    ))
+
+(defun web-mode-fontify-region (beg end keywords)
+  "Highlight block."
+  (save-excursion
+;;    (message "beg=%S end=%S" beg end)
+    (let ((font-lock-keywords keywords)
+          (font-lock-multiline nil)
+          (font-lock-keywords-case-fold-search (member web-mode-engine
+                                                       '("asp"
+                                                         "template-toolkit")))
+          (font-lock-keywords-only t)
+          (font-lock-extend-region-functions nil)
+          )
+      (font-lock-fontify-region beg end)
+      ))
+
+  ;; UGLY HACK / workaround (help needed)
+  (unless web-mode-buffer-highlighted
+    (setq web-mode-buffer-highlighted t)
+    (web-mode-fontify-region beg end keywords)
+    )
+  )
+
+(defun web-mode-fill-paragraph (&optional justify)
+  "fill paragraph"
+  (save-excursion
+    (let ((pos (point)) fill-coll
+          prop pair beg end delim-beg delim-end chunk fill-col)
+      (cond
+       ((or (eq (get-text-property pos 'part-token) 'comment)
+            (eq (get-text-property pos 'block-token) 'comment))
+        (setq prop
+              (if (get-text-property pos 'part-token) 'part-token 'block-token))
+        (setq pair (web-mode-property-boundaries prop pos))
+        (when (and pair (> (- (cdr pair) (car pair)) 6))
+          (setq fill-coll (if (< fill-column 10) 70 fill-column))
+          (setq beg (car pair)
+                end (cdr pair))
+          (goto-char beg)
+          (setq chunk (buffer-substring-no-properties beg (+ beg 2)))
+          (cond
+           ((string= chunk "//")
+            (setq delim-beg "//"
+                  delim-end "EOL"))
+           ((string= chunk "/*")
+            (setq delim-beg "/*"
+                 delim-end "*/"))
+           ((string= chunk "{#")
+            (setq delim-beg "{#"
+                  delim-end "#}"))
+           ((string= chunk "<!")
+            (setq delim-beg "<!--"
+                  delim-end "-->"))
+           )
+          ;;          (subst-char-in-region beg end ?\n ?\s)
+          ;;          (message "fill-column=%S pt=%S pair=%S chunk=%S"
+          ;;                   fill-column (point) pair chunk)
+          )
+        );comment - case
+
+       ((web-mode-is-html-text)
+        (setq pair (web-mode-property-boundaries prop pos))
+        (setq beg (previous-property-change pos)
+              end (next-property-change pos))
+        )
+
+       );cond
+      ;;(message "beg%S end%S" beg end)
+      (when (and beg end)
+        (fill-region beg end))
+      t)))
+
+(defun web-mode-property-boundaries (prop &optional pos)
+  "property boundaries (cdr is 1+)"
+  (unless pos (setq pos (point)))
+  (let (beg end val)
+    (setq val (get-text-property pos prop))
+    (if (null val)
+        val
+      (if (or (bobp)
+              (not (eq (get-text-property (1- pos) prop) val)))
+          (setq beg pos)
+        (setq beg (previous-single-property-change pos prop))
+        (when (null beg) (setq beg (point-min))))
+      (if (or (eobp)
+              (not (eq (get-text-property (1+ pos) prop) val)))
+          (setq end pos)
+        (setq end (next-single-property-change pos prop))
+        (when (null end) (setq end (point-min))))
+      (cons beg end))))
+
+(defun web-mode-scan-whitespaces (beg end)
+  "Scan whitespaces."
+  (save-excursion
+    (goto-char beg)
+    (while (re-search-forward web-mode-whitespaces-regexp end t)
+      (add-text-properties (match-beginning 0) (match-end 0)
+                           '(face web-mode-whitespace-face))
+      );while
+    ))
+
+(defun web-mode-errors-show ()
+  "Show unclosed tags."
+  (interactive)
+  (let (beg end tag pos l n tags i cont cell overlay overlays first
+            (ori (point))
+            (errors 0)
+            (continue t)
+        )
+    (setq overlays (overlays-in (point-min) (point-max)))
+    (when overlays
+      (dolist (overlay overlays)
+        (when (eq (overlay-get overlay 'face) 'web-mode-warning-face)
+          (delete-overlay overlay)
+          )
+        )
+      )
+    (goto-char (point-min))
+    (when (not (or (get-text-property (point) 'tag-beg)
+                   (web-mode-tag-next)))
+      (setq continue nil))
+    (while continue
+      (setq pos (point))
+      (setq tag (get-text-property pos 'tag-name))
+      (cond
+       ((eq (get-text-property (point) 'tag-type) 'start)
+        (setq tags (add-to-list 'tags (list tag pos)))
+;;        (message "(%S) opening %S" pos tag)
+        )
+       ((eq (get-text-property (point) 'tag-type) 'end)
+        (setq i 0
+              l (length tags)
+              cont t)
+        (while (and (< i l) cont)
+          (setq cell (nth i tags))
+;;          (message "cell=%S" cell)
+          (setq i (1+ i))
+          (cond
+           ((string= tag (nth 0 cell))
+            (setq cont nil)
+            )
+           (t
+            (setq errors (1+ errors))
+            (setq beg (nth 1 cell))
+            (setq end (web-mode-tag-end-position beg))
+            (unless first
+              (setq first beg))
+            (setq overlay (make-overlay beg (1+ end)))
+            (overlay-put overlay 'face 'web-mode-warning-face)
+;;            (message "invalid <%S> at %S" (nth 0 cell) (nth 1 cell))
+            )
+           );cond
+          );while
+
+        (dotimes (i i)
+          (setq tags (cdr tags))
+;;          (setq cell (nth i tags))
+;;          (message "removing=%S" cell)
+          )
+
+        )
+       );cond
+      (when (not (web-mode-tag-next))
+        (setq continue nil))
+      );while
+    (message "%S error(s) detected" errors)
+    (if (> errors 0)
+        (progn (goto-char first)
+               (recenter))
+      (goto-char ori)
+      );if
+    ;;    (message "%S" tags)
+    ))
+
+(defun web-mode-whitespaces-show ()
+  "Toggle whitespaces."
+  (interactive)
+  (if web-mode-enable-whitespaces
+      (web-mode-whitespaces-off)
+    (web-mode-whitespaces-on))
+  (web-mode-scan-buffer))
+
+(defun web-mode-whitespaces-on ()
+  "Show whitespaces."
+  (interactive)
+  (when (null web-mode-display-table)
+    ;;    http://webdesign.about.com/od/localization/l/blhtmlcodes-ascii.htm
+    (setq web-mode-display-table (make-display-table))
+    (aset web-mode-display-table 9  (vector ?\xBB ?\t)) ;tab
+    (aset web-mode-display-table 10 (vector ?\xB6 ?\n)) ;line feed
+    (aset web-mode-display-table 32 (vector ?\xB7)) ;space
+    );when
+  (when web-mode-hl-line-mode-flag
+    (global-hl-line-mode -1))
+  (setq buffer-display-table web-mode-display-table)
+  (setq web-mode-enable-whitespaces t))
+
+(defun web-mode-whitespaces-off ()
+  "Hide whitespaces."
+  (when web-mode-hl-line-mode-flag
+    (global-hl-line-mode 1))
+  (setq buffer-display-table nil)
+  (setq web-mode-enable-whitespaces nil))
+
+(defun web-mode-buffer-indent ()
+  "Indent all buffer."
+  (interactive)
+  (indent-region (point-min) (point-max))
+  (delete-trailing-whitespace))
+
+(defun web-mode-buffer-refresh ()
+  "Indent and fontify buffer."
+  (interactive)
+  (web-mode-scan-buffer)
+  (web-mode-buffer-indent))
+
+(defun web-mode-previous-usable-server-line ()
+  "Return previous non blank/comment/string line and return this line (trimmed)."
+  (interactive)
+  (save-excursion
+    (let ((continue t)
+          (line "")
+          (pos (point)))
+      (beginning-of-line)
+      (while (and continue
+                  (not (bobp))
+                  (forward-line -1))
+        (if (not (web-mode-is-comment-or-string-line))
+            (setq line (web-mode-trim (buffer-substring (point) (line-end-position)))))
+        (when (not (string= line "")) (setq continue nil))
+        );while
+      (if (string= line "")
+          (progn (goto-char pos) nil)
+        line)
+      )))
+
+(defun web-mode-previous-usable-client-line ()
+  "Return previous non blank/comment/string line and return this line (trimmed)."
+  (interactive)
+  (save-excursion
+    (let ((continue t)
+          (line "")
+          (pos (point)))
+      (beginning-of-line)
+      (while (and continue
+                  (not (bobp))
+                  (forward-line -1))
+        (if (not (web-mode-is-part-token-line))
+            (setq line (web-mode-trim (buffer-substring (point) (line-end-position)))))
+        (when (not (string= line "")) (setq continue nil))
+        )
+      (if (string= line "")
+          (progn (goto-char pos) nil)
+        line)
+      )))
+
+(defun web-mode-in-code-block (open close &optional prop)
+  "Detect if point is in a block delimited by open and close."
+  (save-excursion
+    (let ((pos (point)) pos-open pos-close start end ret)
+      (when prop
+        (setq start pos
+              end pos)
+        (when (eq (get-text-property pos prop) (get-text-property (1- pos) prop))
+          (setq start (or (previous-single-property-change pos prop) (point-min))))
+        (when (eq (get-text-property pos prop) (get-text-property (1+ pos) prop))
+          (setq end (next-single-property-change pos prop)))
+        ;;        (message "start(%S) end(%S)" start end)
+        )
+      (setq ret (and (web-mode-sb open start t)
+                     (setq pos-open (point))
+                     (web-mode-sf close end t)
+                     (setq pos-close (point))
+                     (>= pos-close pos)))
+      (if ret
+          (cons pos-open pos-close)
+        ret)
+      )))
+
+(defun web-mode-line-number (&optional pos)
+  "Return line number at point."
+  (unless pos (setq pos (point)))
+  (let (ret)
+    (setq ret (+ (count-lines 1 pos)
+                 (if (= (web-mode-column-at-pos pos) 0) 1 0)))
+    ret))
+
+(defun web-mode-clean-client-line (input)
+  "Remove comments and server scripts."
+  (let ((out "")
+        (beg 0)
+        (keep t)
+        (n (length input)))
+    (dotimes (i n)
+      (if (or (get-text-property i 'block-side input)
+              (eq (get-text-property i 'part-token input) 'comment))
+          (when keep
+            (setq out (concat out (substring input beg i))
+                  beg 0
+                  keep nil))
+        (when (null keep)
+          (setq beg i
+                keep t))
+        );if
+      ;;      (message "out=%s beg=%d" out beg)
+      );dotimes
+    (if (> beg 0) (setq out (concat out (substring input beg n))))
+    (setq out (if (= (length out) 0) input out))
+    (web-mode-trim out)
+    ;;    (message "%S [%s] > [%s]" beg input out)
+    ))
+
+(defun web-mode-clean-server-line (input)
+  "Remove comments from server line."
+  (let ((out "")
+        (beg 0)
+        (keep t)
+        (n (length input)))
+    (dotimes (i n)
+      (if (eq (get-text-property i 'block-token input) 'comment)
+          (when keep
+            (setq out (concat out (substring input beg i))
+                  beg 0
+                  keep nil))
+        (when (null keep)
+          (setq beg i
+                keep t))
+        );if
+      );dotimes
+    (if (> beg 0) (setq out (concat out (substring input beg n))))
+    (setq out (if (= (length out) 0) input out))
+    (web-mode-trim out)
+    ;;    (message "%S [%s] > [%s]" beg input out)
+    ))
+
+(defun web-mode-column-at-pos (&optional pos)
+  "Column at point"
+  (unless pos (setq pos (point)))
+  (save-excursion
+    (goto-char pos)
+    (current-column)
+    ))
+
+;; doit-on considérer que '=' est un bloc ouvrant avec ';' comme char de fin ?
+(defun web-mode-point-context (pos)
+  "POS should be at the beginning of the indentation.
+   Return ctx = plist containing
+    :block-beg, :block-column,
+    :first-char, :line (trimmed)
+    :type (live, comment, string),
+    :language (html, php, jsp, aspx, asp + javascript, css),
+    :indent-offset
+    :prev-line :prev-char :prev-props"
+  (save-excursion
+    (let (ctx pos-min
+              block-beg block-column first-char line type language indent-offset
+              prev-line prev-char prev-props)
+
+      (setq pos-min (point-min))
+      (setq block-beg pos-min
+            block-column 0
+            type "live"
+            language ""
+            prev-line ""
+            prev-char 0)
+      (cond
+
+       ((bobp)
+        )
+
+       ((string= web-mode-content-type "css")
+        (setq language "css"
+              indent-offset web-mode-css-indent-offset))
+
+       ((member web-mode-content-type '("javascript" "json"))
+        (setq language "javascript"
+              indent-offset web-mode-code-indent-offset))
+
+       ((string= web-mode-content-type "php")
+        (setq language "php"
+              indent-offset web-mode-code-indent-offset))
+
+       ((or (string= web-mode-content-type "xml"))
+        (setq language "xml"
+              indent-offset web-mode-markup-indent-offset))
+
+       ((and (get-text-property pos 'tag-beg)
+             (get-text-property pos 'tag-name))
+        (setq language "html"
+              indent-offset web-mode-markup-indent-offset)
+        )
+
+       ((or (and (eq (get-text-property pos 'part-token) 'comment)
+                 (eq (get-text-property (1- pos) 'part-token) 'comment)
+                 (progn
+                   (setq block-beg (previous-single-property-change pos 'part-token))
+                   t))
+            (and (eq (get-text-property pos 'block-token) 'comment)
+                 (eq (get-text-property (1- pos) 'block-token) 'comment)
+                 (progn
+                   (setq block-beg (previous-single-property-change pos 'block-token))
+                   t)))
+        (setq type "comment"))
+
+       ((or (and (eq (get-text-property pos 'part-token) 'string)
+                 (eq (get-text-property (1- pos) 'part-token) 'string))
+            (and (eq (get-text-property pos 'block-token) 'string)
+                 (eq (get-text-property (1- pos) 'block-token) 'string)))
+        (setq type "string"))
+
+       ((and (get-text-property pos 'block-side)
+             (not (get-text-property pos 'block-beg)))
+        (setq block-beg (or (web-mode-block-beginning-position pos) pos-min))
+        (goto-char block-beg)
+        (setq block-column (current-column))
+        (setq language web-mode-engine)
+        (setq indent-offset web-mode-code-indent-offset)
+        (cond
+         ((string= web-mode-engine "blade")
+          (setq block-beg (+ block-beg 2)
+                block-column (+ block-column 2))
+          )
+         ((string= web-mode-engine "razor")
+          (setq block-beg (+ block-beg 2)
+                block-column (+ block-column 2))
+          )
+         ((string= web-mode-engine "template-toolkit")
+          (setq block-beg (+ block-beg 3)
+                block-column (+ block-column 3))
+          )
+         ((and (string= web-mode-engine "jsp")
+               (web-mode-looking-at-pos "<%@\\|<[[:alpha:]]" block-beg))
+          (save-excursion
+            (goto-char block-beg)
+            (looking-at "<%@[ ]*[[:alpha:]]+[ ]+\\|</?[[:alpha:]]+:[[:alpha:]]+[ ]+")
+            (goto-char (match-end 0))
+            (setq block-column (current-column))
+            )
+          )
+         ((and (string= web-mode-engine "freemarker")
+               (web-mode-looking-at-pos "<@\\|<%@\\|<[[:alpha:]]" block-beg))
+          (save-excursion
+            (goto-char block-beg)
+            (looking-at "<@[[:alpha:].]+[ ]+\\|<%@[ ]*[[:alpha:]]+[ ]+\\|<[[:alpha:]]+:[[:alpha:]]+[ ]+")
+            (goto-char (match-end 0))
+            (setq block-column (current-column))
+            )
+          )
+         );cond
+        )
+
+       ((and (get-text-property pos 'part-side)
+             (get-text-property pos 'part-language))
+        (setq block-beg (or (previous-single-property-change pos 'part-side) pos-min))
+        (goto-char block-beg)
+        (search-backward "<")
+        (setq block-column (current-column))
+        (setq language (symbol-name (get-text-property pos 'part-language)))
+        (cond
+         ((string= language "css")
+          (setq indent-offset web-mode-css-indent-offset)
+          )
+         (t
+          (setq language "javascript"
+                indent-offset web-mode-code-indent-offset)
+          )
+         )
+        )
+
+       (t
+        (setq language "html"
+              indent-offset web-mode-markup-indent-offset)
+        )
+
+       );cond
+
+      (goto-char pos)
+      (setq line (web-mode-trim (buffer-substring-no-properties (line-beginning-position)
+                                                                (line-end-position))))
+      (setq first-char (if (string= line "") 0 (aref line 0)))
+
+      (when (or (member language '("php" "javascript"))
+                (and (string= language "html") (not (eq ?\< first-char))))
+        (cond
+         ((member language '("html" "javascript"))
+          (setq prev-line (web-mode-previous-usable-client-line))
+;;          (message "prev-line=%S" prev-line)
+          (when prev-line
+            (setq prev-line (web-mode-clean-client-line prev-line))
+            (setq prev-props (text-properties-at (1- (length prev-line)) prev-line)))
+          )
+         (t
+          (setq prev-line (web-mode-previous-usable-server-line))
+          (when prev-line
+            (setq prev-line (web-mode-clean-server-line prev-line)))
+          )
+         );cond
+        (when (>= (length prev-line) 1)
+          (setq prev-char (aref prev-line (1- (length prev-line))))
+          (setq prev-line (substring-no-properties prev-line))
+          )
+        )
+
+;;      (if (string= language "json") (setq language "javascript"))
+
+      (when (string= web-mode-content-type "html")
+        (cond
+         ((string= language "javascript")
+          (setq block-column (+ block-column web-mode-script-padding)))
+         ((string= language "css")
+          (setq block-column (+ block-column web-mode-style-padding)))
+         ((not (member language '("html" "razor")))
+          (setq block-column (+ block-column web-mode-block-padding)))
+         )
+        )
+
+      (setq ctx (list :block-beg block-beg
+                      :block-column block-column
+                      :first-char first-char
+                      :line line
+                      :type type
+                      :language language
+                      :indent-offset indent-offset
+                      :prev-line prev-line
+                      :prev-char prev-char
+                      :prev-props prev-props))
+;;      (message "%S" ctx)
+      ctx
+      )))
+
+(defun web-mode-indent-line ()
+  "Indent current line according to language."
+  (let ((inhibit-modification-hooks t)
+        pos
+        offset
+        ctx
+        block-beg
+        block-column
+        first-char
+        line
+        type
+        language
+        indent-offset
+        prev-line
+        prev-char
+        prev-props)
+
+    (save-excursion
+      (back-to-indentation)
+      (setq pos (point))
+      (setq ctx (web-mode-point-context pos))
+      (setq block-beg (plist-get ctx :block-beg))
+      (setq block-column (plist-get ctx :block-column))
+      (setq first-char (plist-get ctx :first-char))
+      (setq line (plist-get ctx :line))
+      (setq type (plist-get ctx :type))
+      (setq language (plist-get ctx :language))
+      (setq indent-offset (plist-get ctx :indent-offset))
+      (setq prev-line (plist-get ctx :prev-line))
+      (setq prev-char (plist-get ctx :prev-char))
+      (setq prev-props (plist-get ctx :prev-props))
+
+      (cond
+
+       ((or (bobp)
+            (= (line-number-at-pos pos) 1))
+        (setq offset 0)
+        )
+
+       ((string= type "string")
+        (setq offset nil)
+        )
+
+       ((string= type "comment")
+        (goto-char (car
+                    (web-mode-property-boundaries
+                     (if (eq (get-text-property pos 'part-token) 'comment)
+                         'part-token
+                       'block-token)
+                     pos)))
+        (setq offset (current-column))
+        (cond
+         ((and (string= (buffer-substring-no-properties (point) (+ (point) 2)) "/*")
+                   (eq ?\* first-char))
+          (setq offset (1+ offset)))
+         ((and (string= web-mode-engine "django")
+               (looking-back "{% comment %}"))
+          (setq offset (- offset 12))
+          )
+         );cond
+        );case comment
+
+       ((member language '("php" "jsp" "asp" "aspx" "javascript" "code" "python" "erb" "freemarker" "blade" "template-toolkit"))
+
+        (cond
+
+         ((string-match-p "^[?%]>" line)
+          (if (web-mode-block-beginning pos)
+              (setq offset (current-column)))
+          )
+
+         ((and (string-match-p "^[=]?%]" line)
+               (string= web-mode-engine "template-toolkit"))
+          (if (web-mode-block-beginning pos)
+              (setq offset (current-column)))
+          )
+
+
+         ((and (string= language "php") (string-match-p "^->" line))
+          (when (web-mode-sb "->" block-beg)
+            (setq offset (current-column)))
+          )
+
+         ((and (string= language "javascript") (eq ?\. first-char))
+          (when (web-mode-rsb "[[:alnum:][:blank:]]\\.[[:alpha:]]" block-beg)
+            (setq offset (1+ (current-column))))
+          )
+
+         ((member first-char '(?\? ?\. ?\:))
+          (web-mode-rsb "[^!=][=(]" block-beg)
+          (setq offset (1+ (current-column)))
+          (when (and (string= web-mode-engine "php")
+                     (looking-at-p " =>"))
+            (setq offset (1+ offset))
+            )
+          )
+
+         ((and (member prev-char '(?\. ?\+ ?\? ?\:))
+               (not (string-match-p "^\\(case\\|default\\)[ :]" prev-line)))
+          (web-mode-rsb "[=(]" block-beg)
+          (skip-chars-forward "= (")
+          (setq offset (current-column))
+          )
+
+         ((string= language "erb")
+          (setq offset (web-mode-ruby-indentation pos
+                                                  line
+                                                  block-column
+                                                  indent-offset
+                                                  block-beg))
+          )
+
+         ((string= language "asp")
+          (setq offset (web-mode-asp-indentation pos
+                                                 line
+                                                 block-column
+                                                 indent-offset
+                                                 block-beg))
+          )
+
+         (t
+          (setq offset (web-mode-bracket-indentation pos
+                                                     block-column
+                                                     indent-offset
+                                                     block-beg))
+          );t
+
+         ));end case script block
+
+       ((string= language "css")
+        (setq offset (web-mode-bracket-indentation pos
+                                                   block-column
+                                                   indent-offset
+                                                   block-beg))
+        );case style
+
+       (t ; case html block
+
+        (cond
+
+         ((and prev-props (eq (plist-get prev-props 'part-token) 'attr))
+          (web-mode-tag-beginning)
+          (let (skip)
+            (setq skip (next-single-property-change (point) 'part-token))
+            (when skip
+              (goto-char skip)
+              (setq offset (current-column))
+              ))
+          )
+
+         ((or (and (eq (get-text-property pos 'tag-type) 'end)
+                   (web-mode-match-html-tag))
+              (and (get-text-property pos 'block-beg)
+                   (looking-at-p web-mode-close-block-regexp)
+                   (funcall web-mode-engine-control-matcher))
+              )
+          (setq offset (current-indentation))
+          )
+
+         ((or (eq (length line) 0)
+              (= web-mode-indent-style 2)
+              (get-text-property pos 'tag-beg)
+              (get-text-property pos 'block-beg))
+          (setq offset (web-mode-markup-indentation pos))
+          )
+
+         );cond
+
+        );end case html block
+
+       );end switch language block
+
+      );save-excursion
+
+    (when offset
+      (let ((diff (- (current-column) (current-indentation))))
+        (setq offset (max 0 offset))
+        (indent-line-to offset)
+        (if (> diff 0) (forward-char diff))
+        );let
+      );when
+
+    ))
+
+(defun web-mode-is-active-block (pos)
+  "web-mode-is-active-block"
+  (save-excursion
+    (let (ctrl state)
+      (goto-char pos) ;;(message "pos=%S" pos)
+      (when (looking-at web-mode-active-block-regexp)
+
+        (cond
+
+         ((string= web-mode-engine "php")
+          (setq ctrl (match-string-no-properties 3))
+          (if (member ctrl '("else" "elseif"))
+              (setq ctrl nil)
+            (setq state (not (string= "end" (match-string-no-properties 2))))
+            )
+          )
+
+         ((string= web-mode-engine "django")
+          (setq ctrl (match-string-no-properties 2))
+          (if (member ctrl '("else" "elseif" "elif" "empty"))
+              (setq ctrl nil)
+            (setq state (not (string= "end" (match-string-no-properties 1))))
+            )
+          )
+
+         ((string= web-mode-engine "smarty")
+          (setq ctrl (match-string-no-properties 1))
+          (if (member ctrl '("else" "elseif"))
+              (setq ctrl nil)
+            (setq state (not (eq ?\/ (aref (match-string-no-properties 0) 1))))
+            )
+          )
+
+         ((string= web-mode-engine "dust")
+          (setq ctrl (match-string-no-properties 1))
+          (if (or (member ctrl '("else"))
+                  (eq ?\/ (char-after (1- (web-mode-block-end-position)))))
+              (setq ctrl nil)
+            (setq state (not (eq ?\/ (aref (match-string-no-properties 0) 1))))
+            )
+          )
+
+         ((string= web-mode-engine "closure")
+          (setq ctrl (match-string-no-properties 1))
+          (if (or (member ctrl '("else" "elseif" "case" "default"))
+                  (eq ?\/ (char-after (1- (web-mode-block-end-position)))))
+              (setq ctrl nil)
+            (setq state (not (eq ?\/ (aref (match-string-no-properties 0) 1))))
+            )
+          )
+
+         ((string= web-mode-engine "ctemplate")
+          (setq ctrl (match-string-no-properties 1))
+          (setq state (not (eq ?\/ (aref (match-string-no-properties 0) 2))))
+          )
+
+         ((string= web-mode-engine "velocity")
+          (setq ctrl (match-string-no-properties 1))
+          (if (member ctrl '("else" "elseif"))
+              (setq ctrl nil)
+            (setq state (not (string= "end" (match-string-no-properties 1))))
+            )
+          )
+
+         ((string= web-mode-engine "blade")
+          (setq ctrl (match-string-no-properties 2))
+          (cond
+           ((string= ctrl "stop")
+            (setq ctrl "section"))
+           ((member ctrl '("else" "elseif"))
+            (setq ctrl nil))
+           (t
+            (setq state (not (string= "end" (match-string-no-properties 1)))))
+           )
+          )
+
+         ((string= web-mode-engine "go")
+          (setq ctrl (match-string-no-properties 1))
+          (if (member ctrl '("else"))
+              (setq ctrl nil)
+            (setq state (not (string= "end" ctrl)))
+            )
+          )
+
+         ((string= web-mode-engine "erb")
+          (setq ctrl (match-string-no-properties 1))
+          (if (member ctrl '("else"))
+              (setq ctrl nil)
+            (setq state (not (string= "end" ctrl)))
+            )
+          )
+
+         ((string= web-mode-engine "template-toolkit")
+          (setq ctrl (match-string-no-properties 1))
+          (if (member ctrl '("else"))
+              (setq ctrl nil)
+            (setq state (not (string= "end" ctrl)))
+            )
+          )
+
+         ((string= web-mode-engine "jsp")
+          (cond
+           ((eq (aref (match-string-no-properties 0) 1) ?\%)
+            (setq ctrl (match-string-no-properties 2)
+                  state t)
+            )
+           (t
+            (setq ctrl (match-string-no-properties 1))
+            (if (or (member ctrl '("h:inputtext" "jsp:usebean" "jsp:forward" "struts:property"))
+                    (eq ?\/ (char-after (1- (web-mode-block-end-position)))))
+                (setq ctrl nil)
+              (setq state (not (eq ?\/ (aref (match-string-no-properties 0) 1))))
+              )
+            )
+           )
+          )
+
+         ((string= web-mode-engine "freemarker")
+          (if (or (member (aref (match-string-no-properties 0) 1) '(?\@ ?\#))
+                  (member (aref (match-string-no-properties 0) 2) '(?\@ ?\#)))
+              (setq ctrl (match-string-no-properties 2))
+            (setq ctrl (match-string-no-properties 1))
+            )
+;;          (message "ctrl=%S" ctrl)
+          (if (or (member ctrl '("include" "setting" "import" "global" "ftl"
+                                 "nested" "return" "local" "flush" "break" "recover"))
+                  (eq ?\/ (char-after (1- (web-mode-block-end-position)))))
+              (setq ctrl nil)
+            (setq state (not (eq ?\/ (aref (match-string-no-properties 0) 1))))
+            )
+          )
+
+         ((string= web-mode-engine "underscore")
+          (cond
+           ((web-mode-block-ends-with "{ %>")
+            (setq ctrl "ctrl"
+                  state t))
+           ((looking-at-p "<% }")
+            (setq ctrl "ctrl"
+                  state nil))
+           )
+          )
+
+         );cond
+
+        );when
+
+;;      (message "engine=%S ctrl=%S state=%S" web-mode-engine ctrl state)
+
+      (if ctrl (cons ctrl state) nil)
+      )))
+
+(defun web-mode-markup-indentation-origin ()
+  "web-mode-indentation-origin-pos"
+  (let ((continue t) pos)
+    (while continue
+      (forward-line -1)
+      (back-to-indentation)
+      (setq continue (not (bobp)))
+      (when (or (get-text-property (point) 'tag-beg)
+                (and (get-text-property (point) 'block-beg)
+                     (web-mode-is-active-block (point))
+                     (not (looking-at-p "{% comment"))))
+        (setq continue nil
+              pos (point))
+        )
+      );while
+    (message "indent-origin=%S" pos)
+    pos
+    ))
+
+(defun web-mode-markup-indentation (pos)
+  "markup indentation"
+  (save-excursion
+    (goto-char pos)
+    (let ((offset 0) beg ret)
+      (setq beg (web-mode-markup-indentation-origin))
+      (when beg
+        (goto-char beg)
+        (setq ret (web-mode-is-opened-element beg pos))
+        (cond
+         ((null ret)
+          (setq offset (current-indentation)))
+         ((eq ret t)
+          (setq offset (+ (current-indentation) web-mode-markup-indent-offset))
+          )
+         (t
+          (setq offset ret))
+         )
+;;        (setq offset (+ (current-indentation)
+;;                        (if (web-mode-is-opened-element beg pos)
+;;                            web-mode-markup-indent-offset
+;;                          0)))
+        );when
+      offset
+      )))
+
+;; state(t) <=> start tag
+(defun web-mode-is-opened-element (pos limit)
+  "Is there any HTML element without a closing tag ?"
+  (interactive)
+  (let (tag
+        last-tag
+        tag-pos block-pos
+        state
+        n
+        ret
+        (continue t)
+        (buffer (current-buffer))
+        (h (make-hash-table :test 'equal))
+        (h2 (make-hash-table :test 'equal))
+        ctrl)
+    (while continue
+      (setq ctrl nil
+            last-tag nil)
+      (when (or (and (get-text-property pos 'tag-beg)
+                     (member (get-text-property pos 'tag-type) '(start end)))
+                (and (get-text-property pos 'block-beg)
+                     (setq ctrl (web-mode-is-active-block pos))))
+        (if ctrl
+            (setq tag (car ctrl)
+                  state (cdr ctrl))
+          (setq tag (get-text-property pos 'tag-name)
+                state (eq (get-text-property pos 'tag-type) 'start))
+          (if (null state) (setq last-tag (cons tag pos)))
+          )
+
+        (setq n (gethash tag h 0))
+        (if (null state)
+            (progn
+              (when (> n 0) (puthash tag (1- n) h))
+              (puthash tag (1- n) h2))
+          (puthash tag (1+ n) h)
+          (puthash tag (1+ n) h2))
+        );when
+      (setq pos (1+ pos))
+      (when (null tag-pos)
+        (setq tag-pos (next-single-property-change pos 'tag-beg buffer limit)))
+      (when (null block-pos)
+        (setq block-pos (next-single-property-change pos 'block-beg buffer limit)))
+      (cond
+       ((and (null tag-pos)
+             (null block-pos))
+        (setq pos nil)
+        )
+       ((or (null block-pos)
+            (< tag-pos block-pos))
+        (setq pos tag-pos)
+        (setq tag-pos nil)
+        )
+       (t
+        (setq pos block-pos)
+        (setq block-pos nil)
+        )
+       )
+      (when (or (null pos)
+                (>= pos limit))
+        (setq continue nil))
+      );while
+;;    (message "hashtable=%S" h)
+    (maphash (lambda (k v) (if (> v 0) (setq ret t))) h)
+    (when (and (null ret)
+               last-tag
+               (> (hash-table-count h2) 1)
+               (< (gethash (car last-tag) h2) 0))
+;;      (message "last-tag=%S" last-tag)
+      (save-excursion
+        (goto-char (cdr last-tag))
+        (web-mode-match-html-tag)
+        (when (not (= (point) (cdr last-tag)))
+          (setq n (point))
+          (back-to-indentation)
+          (if (= n (point)) (setq ret (current-indentation))))
+        ))
+    ret))
+
+(defun web-mode-ruby-indentation (pos line initial-column language-offset limit)
+  "Calc indent column."
+  (interactive)
+  (unless limit (setq limit nil))
+  (let (h out prev-line prev-indentation)
+    (setq h (web-mode-previous-line pos limit))
+    (setq out initial-column)
+    (when h
+      (setq prev-line (car h))
+      (setq prev-indentation (cdr h))
+      (cond
+       ((string-match-p "^\\(end\\|else\\|elsif\\|when\\)" line)
+        (setq out (- prev-indentation language-offset))
+        )
+       ((string-match-p "\\(when\\|if\\|else\\|elsif\\|unless\\|for\\|while\\|def\\|class\\)" prev-line)
+        (setq out (+ prev-indentation language-offset))
+        )
+       (t
+        (setq out prev-indentation)
+        )
+       )
+      );when
+    out
+    ))
+
+(defun web-mode-asp-indentation (pos line initial-column language-offset limit)
+  "Calc indent column."
+  (interactive)
+  (unless limit (setq limit nil))
+  (let (h out prev-line prev-indentation)
+    (setq h (web-mode-previous-line pos limit))
+    (setq out initial-column)
+    (when h
+      (setq prev-line (car h))
+      (setq prev-indentation (cdr h))
+      (cond
+       ;; ----------------------------------------------------------------------
+       ;; unindent
+       ((string-match-p "\\<\\(\\(end \\(if\\|function\\|class\\|sub\\|with\\)\\)\\|else\\|elseif\\|next\\|loop\\)\\>" line)
+        (setq out (- prev-indentation language-offset)))
+       ;; ----------------------------------------------------------------------
+       ;; select case statement
+       ((string-match-p "\\<\\(select case\\)\\>" line)
+        (setq out (- prev-indentation 0)))
+       ((string-match-p "\\<\\(end select\\)" line)
+        (setq out (- prev-indentation (* 2 language-offset))))
+       ((and (string-match-p "\\<\\(case\\)\\>" line) (not (string-match-p "\\<\\(select case\\)\\>" prev-line)))
+        (setq out (- prev-indentation language-offset)))
+       ;; ----------------------------------------------------------------------
+       ;; do nothing
+       ((string-match-p "\\<\\(\\(end \\(if\\|function\\|class\\|sub\\|select\\|with\\)\\)\\|loop\\( until\\| while\\)?\\)\\>" prev-line)
+        (setq out (+ prev-indentation 0)))
+       ;; indent
+       ((string-match-p "\\<\\(\\(select \\)?case\\|else\\|elseif\\|unless\\|for\\|class\\|with\\|do\\( until\\| while\\)?\\|while\\|\\(public \\|private \\)?\\(function\\|sub\\|class\\)\\)\\>" prev-line)
+        (setq out (+ prev-indentation language-offset)))
+       ;; single line if statement
+       ((string-match-p "\\<if\\>.*\\<then\\>[ \t]*[[:alpha:]]+" prev-line)
+        (setq out (+ prev-indentation 0)))
+       ;; normal if statement
+       ((string-match-p "\\<\\if\\>" prev-line)
+        (setq out (+ prev-indentation language-offset)))
+       (t
+        (setq out prev-indentation))
+       )
+      );when
+    out
+    ))
+
+(defun web-mode-previous-line (pos limit)
+  "Previous line"
+  (save-excursion
+    (let (beg end line (continue t))
+      (goto-char pos)
+      (while continue
+        (forward-line -1)
+        (setq end (line-end-position))
+        (setq line (buffer-substring-no-properties (point) end))
+        (when (or (not (string-match-p "^[ \t]*$" line))
+                  (bobp)
+                  (<= (point) limit))
+          (setq continue nil))
+        )
+      (if (<= (point) limit)
+          ;;todo : affiner (le + 3 n est pas générique cf. <?php <% <%- etc.)
+          (setq beg (if (< (+ limit 3) end) (+ limit 3) end))
+        (setq beg (line-beginning-position))
+        );if
+      (setq line (buffer-substring-no-properties beg end))
+      ;;      (message "line=%s" line)
+      (cons line (current-indentation))
+      )))
+
+(defun web-mode-bracket-indentation (pos initial-column language-offset &optional limit)
+  "Calc indent column."
+  (interactive)
+  (unless limit (setq limit nil))
+  (save-excursion
+    (let (offset n first-char block-info col block-column (continue t))
+      (goto-char pos)
+      (setq first-char (char-after)
+            block-column initial-column)
+      (while continue
+        (forward-line -1)
+        (back-to-indentation)
+        (cond
+         ((or (> limit (point))
+              (bobp))
+          (setq continue nil)
+          )
+         ((and (= (current-indentation) initial-column)
+               (not (eolp)))
+          (setq continue nil)
+          (setq limit (point))
+          )
+         )
+        )
+;;      (message "ic=%S point=%S limit=%S" initial-column (point) limit)
+      (goto-char pos)
+
+      (setq block-info (web-mode-count-opened-blocks pos limit))
+      (setq col initial-column)
+;;      (message "bi=%S" block-info)
+      (if (cddr block-info)
+          (progn
+            (setq col (car (cdr block-info)))
+            )
+        (setq n (car block-info))
+        (setq col initial-column)
+;;        (message "initial-col=%S n=%S col=%S" initial-column n col)
+        (if (member first-char '(?\} ?\) ?\])) (setq n (1- n)))
+        (setq col (+ initial-column (* n language-offset)))
+        );if
+      (if (< col block-column) block-column col)
+      )))
+
+;; return (opened-blocks . (col-num . arg-inline))
+(defun web-mode-count-opened-blocks (pos &optional limit)
+  "Count opened opened block at point."
+  (interactive)
+  (unless limit (setq limit nil))
+  (save-excursion
+    (goto-char pos)
+    (let ((continue t)
+          (match "")
+          (case-found nil)
+          (case-count 0)
+          (queues (make-hash-table :test 'equal))
+          (opened-blocks 0)
+          (col-num 0)
+          (regexp "[\]\[}{)(]\\|\\(break\\|case\\|default\\)")
+          (num-opened 0)
+          close-char n queue arg-inline arg-inline-checked char lines)
+
+      (while (and continue (re-search-backward regexp limit t))
+        (unless (web-mode-is-comment-or-string)
+          (setq match (match-string-no-properties 0)
+                char (char-after))
+
+          (cond
+
+           ((member char '(?\{ ?\( ?\[))
+            (cond
+             ((eq char ?\() (setq close-char ?\)))
+             ((eq char ?\{) (setq close-char ?\}))
+             ((eq char ?\[) (setq close-char ?\])))
+
+            (setq queue (gethash char queues nil))
+            (setq queue (push (cons (point) (web-mode-line-number)) queue))
+            (puthash char queue queues)
+            ;;(message "%c queue=%S" char queue)
+
+            (setq queue (gethash close-char queues nil))
+            (setq n (length queue))
+            (cond
+             ((> n 0)
+              (setq queue (cdr queue))
+              (puthash close-char queue queues)
+              ;;(message "%c queue=%S" close-char queue)
+              (setq queue (gethash char queues nil))
+              (setq queue (cdr queue))
+              (puthash char queue queues)
+              ;;(message "%c queue=%S" char queue)
+              )
+             ((= n 0)
+              (setq num-opened (1+ num-opened))
+              ;;(message "num-opened=%S %S" num-opened (point))
+              )
+             )
+
+            (when (and (= num-opened 1) (null arg-inline-checked))
+              (setq arg-inline-checked t)
+;;              (when (not (member (char-after (1+ (point))) '(?\n ?\r ?\{)))
+              (when (not (looking-at-p ".[ ]*$"))
+                (setq arg-inline t
+                      continue nil
+                      col-num (1+ (current-column))))
+;;              (message "pt=%S" (point))
+              )
+
+            );case
+
+           ((member char '(?\} ?\) ?\]))
+            (setq queue (gethash char queues nil))
+            (setq queue (push (point) queue))
+            (puthash char queue queues)
+            ;;            (message "%c queue=%S" char queue)
+            )
+
+           ((member match '("case" "default"))
+            (setq case-found t
+                  case-count (1+ case-count))
+            )
+
+           ((string= match "break")
+            (setq case-count (1- case-count))
+            )
+
+           );cond
+
+          );unless
+        );while
+
+      (unless arg-inline
+        (maphash
+         (lambda (char queue)
+           (when (member char '(?\{ ?\( ?\[))
+             ;;(message "%c => %S" char queue)
+             (dolist (pair queue)
+               (setq n (cdr pair))
+               (unless (member n lines)
+                 (push n lines))
+               )
+             );when
+           )
+         queues)
+        (setq opened-blocks (length lines))
+        (when (and case-found (> case-count 0))
+          (goto-char pos)
+          (back-to-indentation)
+          (when (not (looking-at-p "case\\|}"))
+            (setq opened-blocks (1+ opened-blocks))
+            )
+          )
+        );unless
+
+;;      (message "opened-blocks(%S) col-num(%S) arg-inline(%S)" opened-blocks col-num arg-inline)
+
+      (cons opened-blocks (cons col-num arg-inline))
+
+      )))
+
+(defun web-mode-count-char-in-string (char string)
+  "Count char in string."
+  (let ((n 0))
+    (dotimes (i (length string))
+      (if (eq (elt string i) char)
+          (setq n (1+ n))))
+    n))
+
+(defun web-mode-scan-at-pos ()
+  "web mode scan at point"
+  (save-excursion
+    (let (scan-beg scan-end (pos (point)))
+      (cond
+       ((web-mode-rsb-client "^[ ]*<")
+        (setq scan-beg (point))
+        (goto-char pos)
+        (setq scan-end (if (web-mode-rsf-client "[[:alnum:] /\"]>[ ]*$") (point) (point-max)))
+        ;;              (message "scan-end=%S" scan-end)
+        ;;            (setq scan-end (point-max))
+        )
+       (t
+        (setq scan-beg 1
+              scan-end (point-max))
+        )
+       );cond
+      ;;(message "scan-region (%S) > (%S)" scan-beg scan-end)
+      ;;          (setq scan-end (point-max))
+      (web-mode-scan-region scan-beg scan-end)
+      );save-excursion
+    ))
+
+(defun web-mode-mark-and-expand ()
+  "Mark and expand."
+  (interactive)
+;;  (message "last-input-event=%S" last-input-event)
+  (web-mode-mark (point)))
+
+;; todo : pb du engine=go ... selection d'un bloc
+(defun web-mode-mark (pos)
+  "Mark at point."
+
+  (let ((beg pos) (end pos) prop reg-beg boundaries)
+
+    (if mark-active
+        (setq reg-beg (region-beginning))
+      (setq web-mode-expand-initial-pos (point)))
+
+    ;;    (message "regs=%S %S %S %S" (region-beginning) (region-end) (point-min) (point-max))
+
+    ;;    (message "before=%S" web-mode-expand-previous-state)
+
+    (cond
+
+     ((and mark-active
+           (= (region-beginning) (point-min))
+           (or (= (region-end) (point-max)) (= (1+ (region-end)) (point-max))))
+      (deactivate-mark)
+      (goto-char (or web-mode-expand-initial-pos (point-min)))
+      (recenter))
+
+    ((and (member (get-text-property pos 'block-token) '(comment string))
+          (not (string= web-mode-expand-previous-state "block-token")))
+
+      (when (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token))
+        (setq beg (or (previous-single-property-change pos 'block-token) (point-min))))
+      (when (eq (get-text-property pos 'block-token) (get-text-property (1+ pos) 'block-token))
+        (setq end (next-single-property-change pos 'block-token)))
+      (set-mark beg)
+      (goto-char end)
+      (exchange-point-and-mark)
+      (setq web-mode-expand-previous-state "block-token"))
+
+     ((and (eq (get-text-property pos 'block-side) t)
+           (not (member web-mode-engine '(django go)))
+           (setq boundaries (web-mode-in-code-block "{" "}" 'block-side))
+           (not (string= web-mode-expand-previous-state "server-block")))
+      (set-mark (car boundaries))
+      (goto-char (cdr boundaries))
+      ;;      (message "char=[%c]" (char-before (- (point) 1)))
+      (if (eq ?\% (char-before (- (point) 1)))
+          (setq web-mode-expand-previous-state "block-side")
+        (setq web-mode-expand-previous-state "server-block"))
+      (exchange-point-and-mark)
+      )
+
+     ((and (eq (get-text-property pos 'block-side) t)
+           (not (string= web-mode-expand-previous-state "block-side")))
+      (when (eq (get-text-property pos 'block-side) (get-text-property (1- pos) 'block-side))
+        (setq beg (or (previous-single-property-change pos 'block-side) (point-min))))
+      (when (eq (get-text-property pos 'block-side) (get-text-property (1+ pos) 'block-side))
+        (setq end (next-single-property-change pos 'block-side)))
+      (set-mark beg)
+      (goto-char end)
+      (exchange-point-and-mark)
+      (setq web-mode-expand-previous-state "block-side"))
+
+     ((and (member (get-text-property pos 'part-token) '(comment string))
+           (not (string= web-mode-expand-previous-state "part-token")))
+
+      (when (eq (get-text-property pos 'part-token) (get-text-property (1- pos) 'part-token))
+        (setq beg (previous-single-property-change pos 'part-token)))
+      (when (eq (get-text-property pos 'part-token) (get-text-property (1+ pos) 'part-token))
+        (setq end (next-single-property-change pos 'part-token)))
+      (set-mark beg)
+      (goto-char end)
+      (exchange-point-and-mark)
+      (setq web-mode-expand-previous-state "part-token"))
+
+     ((and (get-text-property pos 'part-side)
+           (not (string= web-mode-expand-previous-state "client-part"))
+           (setq boundaries (web-mode-in-code-block "{" "}" 'part-side)))
+      (set-mark (car boundaries))
+      (goto-char (cdr boundaries))
+      (exchange-point-and-mark)
+      (setq web-mode-expand-previous-state "client-part")
+      )
+
+     ((and (eq (get-text-property pos 'part-side) t)
+           (not (string= web-mode-expand-previous-state "part-side")))
+
+      (when (eq (get-text-property pos 'part-side) (get-text-property (1- pos) 'part-side))
+        (setq beg (previous-single-property-change pos 'part-side)))
+      (when (eq (get-text-property pos 'part-side) (get-text-property (1+ pos) 'part-side))
+        (setq end (next-single-property-change pos 'part-side)))
+      (set-mark beg)
+      (goto-char end)
+      (exchange-point-and-mark)
+      (setq web-mode-expand-previous-state "part-side"))
+
+     ;;     ((and (eq (get-text-property pos 'markup-type) 'attr)
+     ((and (eq (get-text-property pos 'part-token) 'attr)
+           (not (string= web-mode-expand-previous-state "html-attr")))
+
+      ;; todo: tester que le car précédent n'est pas un
+      (when (eq (get-text-property pos 'part-token) (get-text-property (1- pos) 'part-token))
+        (setq beg (previous-single-property-change pos 'part-token)))
+      (when (eq (get-text-property pos 'part-token) (get-text-property (1+ pos) 'part-token))
+        (setq end (next-single-property-change pos 'part-token)))
+      (set-mark beg)
+      (goto-char end)
+      (exchange-point-and-mark)
+      (setq web-mode-expand-previous-state "html-attr"))
+
+     ((and mark-active
+           (eq ?\< (char-after)))
+
+      (web-mode-element-parent)
+      (if (= reg-beg (region-beginning))
+          (mark-whole-buffer)
+        (web-mode-element-select))
+      )
+
+     (t
+      (web-mode-element-select)
+      ;;(mark-whole-buffer)
+      )
+
+     ) ; cond
+
+;;    (message "after=%S" web-mode-expand-previous-state)
+
+    ))
+
+(defun web-mode-block-select ()
+  "Select the current block."
+  (interactive)
+  (let (beg)
+    (setq beg (web-mode-block-beginning-position (point)))
+    (when beg
+      (goto-char beg)
+      (set-mark (point))
+      (web-mode-block-end)
+      (exchange-point-and-mark)
+      )
+    beg))
+
+(defun web-mode-tag-select ()
+  "Select the current HTML tag."
+  (interactive)
+  (let (beg)
+    (setq beg (web-mode-tag-beginning-position (point)))
+    (when beg
+      (goto-char beg)
+      (set-mark (point))
+      (web-mode-tag-end)
+      (exchange-point-and-mark)
+      )
+    beg))
+
+(defun web-mode-element-content-select ()
+  "Select the content of a HTML element."
+  (interactive)
+  (let (pos beg end)
+    (web-mode-element-select)
+    (when mark-active
+      (setq pos (point))
+      (deactivate-mark)
+      (web-mode-tag-match)
+      (setq end (point))
+      (goto-char pos)
+      (web-mode-tag-end)
+      (set-mark (point))
+      (goto-char end)
+      (exchange-point-and-mark)
+      )))
+
+(defun web-mode-element-select ()
+  "Select the current HTML element (including opening and closing tags)."
+  (interactive)
+  (let (type (pos (point)))
+    (setq type (get-text-property pos 'tag-type))
+    (if type
+        (cond
+         ((member type '(start void))
+          (web-mode-tag-beginning)
+          (set-mark (point))
+          (web-mode-tag-match)
+          (web-mode-tag-end)
+          (exchange-point-and-mark))
+         (t
+          (web-mode-tag-match)
+          (set-mark (point))
+          (web-mode-tag-match)
+          (web-mode-tag-end)
+          (exchange-point-and-mark))
+         );cond
+      (web-mode-element-parent)
+      (unless (= (point) pos) (web-mode-element-select))
+      );if
+    ))
+
+(defun web-mode-element-kill ()
+  "Kill the current HTML element."
+  (interactive)
+  (web-mode-element-select)
+  (when mark-active
+    (kill-region (region-beginning) (region-end))))
+
+(defun web-mode-block-kill ()
+  "Kill the current block."
+  (interactive)
+  (web-mode-block-select)
+  (when mark-active
+    (kill-region (region-beginning) (region-end))))
+
+(defun web-mode-element-clone ()
+  "Clone the current HTML element."
+  (interactive)
+  (let ((offset 0))
+    (web-mode-element-select)
+    (when mark-active
+      (save-excursion
+        (goto-char (region-beginning))
+        (setq offset (current-column)))
+      (kill-region (region-beginning) (region-end))
+      (yank)
+      (newline)
+      (indent-line-to offset)
+      (yank))))
+
+(defun web-mode-element-rename ()
+  "Rename the current HTML element."
+  (interactive)
+  (save-excursion
+    (let (pos tag-name)
+      (setq tag-name (read-from-minibuffer "Tag name? "))
+      (when (and (> (length tag-name) 0)
+                 (web-mode-element-beginning)
+                 (looking-at "<\\([[:alnum:]]+\\)"))
+        (setq pos (point))
+        (unless (web-mode-is-void-element)
+            (save-match-data
+              (web-mode-tag-match)
+              (if (looking-at "</[ ]*\\([[:alnum:]]+\\)")
+                  (replace-match (concat "</" tag-name))
+                )))
+        (goto-char pos)
+        (replace-match (concat "<" tag-name))
+        (web-mode-scan-at-pos)
+        ))))
+
+(defun web-mode-current-trimmed-line ()
+  "Line at point, trimmed."
+  (web-mode-trim (buffer-substring-no-properties
+                  (line-beginning-position)
+                  (line-end-position))))
+
+(defun web-mode-trim (string)
+  "Remove white spaces in beginning and ending of STRING."
+  (replace-regexp-in-string "\\`[ \t\n]*" "" (replace-regexp-in-string "[ \t\n]*\\'" "" string)))
+
+(defun web-mode-is-void-element (&optional tag)
+  "Test if tag is a void tag."
+  (if tag
+      (car (member (downcase tag) web-mode-void-elements))
+    (eq (get-text-property (point) 'tag-type) 'void)
+    ))
+
+(defun web-mode-fold-or-unfold ()
+  "Toggle folding on an HTML element or a control block."
+  (interactive)
+  (web-mode-with-silent-modifications
+   (save-excursion
+     (let (beg-inside beg-outside end-inside end-outside overlay overlays regexp)
+       (back-to-indentation)
+       (setq overlays (overlays-at (point)))
+       (cond
+        ;; *** unfolding
+        (overlays
+         (setq overlay (car overlays))
+         (setq beg-inside (overlay-start overlay)
+               end-inside (overlay-end overlay))
+         (remove-overlays beg-inside end-inside)
+         (put-text-property beg-inside end-inside 'invisible nil)
+         )
+        ;; *** tag folding
+        ((eq (get-text-property (point) 'tag-type) 'start)
+         (setq beg-outside (point))
+         (web-mode-tag-end)
+         (setq beg-inside (point))
+         (goto-char beg-outside)
+         (when (web-mode-tag-match)
+           (setq end-inside (point))
+           (web-mode-tag-end)
+           (setq end-outside (point)))
+         )
+        ;; *** block folding
+        ((cdr (web-mode-is-active-block (point)))
+         (setq beg-outside (point))
+         (web-mode-block-end)
+         (setq beg-inside (point))
+         (goto-char beg-outside)
+         (when (web-mode-tag-match)
+           (setq end-inside (point))
+           (web-mode-block-end)
+           (setq end-outside (point)))
+         )
+        );cond
+       (when end-outside
+         ;;          (message "beg-out(%d) beg-in(%d) end-in(%d) end-out(%d)" beg-outside beg-inside end-inside end-outside)
+         (setq overlay (make-overlay beg-outside end-outside))
+         (overlay-put overlay 'face 'web-mode-folded-face)
+         (put-text-property beg-inside end-inside 'invisible t)
+         )
+       ))))
+
+(defun web-mode-toggle-comments ()
+  "Toggle comments visbility"
+  (interactive)
+  (save-excursion
+    (if web-mode-comments-invisible
+        (remove-overlays))
+    (setq web-mode-comments-invisible (null web-mode-comments-invisible))
+    (let ((continue t)
+          (pos (point-min))
+          (visibility web-mode-comments-invisible)
+          overlay end)
+      (while continue
+        (setq pos (next-single-property-change pos 'face))
+        (if (null pos)
+            (setq continue nil)
+          (when (eq (get-text-property pos 'face) 'web-mode-comment-face)
+            (setq end (next-single-property-change pos 'face))
+            (put-text-property pos end 'invisible visibility)
+            (when visibility
+              (setq overlay (make-overlay pos end)))
+            (goto-char pos)
+            )
+          )
+        )
+      );let
+    ))
+
+(defun web-mode-is-single-line-block (pos)
+  "Is block at POS spread on a single line ?"
+  (= (web-mode-line-number (web-mode-block-beginning-position pos))
+     (web-mode-line-number (web-mode-block-end-position pos))))
+
+(defun web-mode-comment-or-uncomment (&optional pos)
+  "Comment or uncomment line(s), block or region at POS."
+  (interactive)
+  (save-excursion
+    (unless pos (setq pos (if mark-active (region-beginning) (point))))
+    (goto-char pos)
+    (skip-chars-forward "[:space:]" (line-end-position))
+    (if (web-mode-is-comment)
+	(web-mode-uncomment (point))
+      (web-mode-comment (point))))
+  (web-mode-scan-region (point-min) (point-max)))
+
+(defun web-mode-comment (pos)
+  "Comment line(s) at point."
+  (interactive)
+  (save-excursion
+    (let (ctx language sel beg end tmp block-side single-line-block)
+
+      (setq block-side (get-text-property pos 'block-side))
+      (setq single-line-block (web-mode-is-single-line-block pos))
+
+      (cond
+
+       ((and block-side
+             (string= web-mode-engine "django")
+             single-line-block)
+        (web-mode-comment-django-block pos)
+        )
+
+       ((and block-side
+             (string= web-mode-engine "dust")
+             single-line-block)
+        (web-mode-comment-dust-block pos)
+        )
+
+       ((and block-side
+             (string= web-mode-engine "erb")
+             single-line-block)
+        (web-mode-comment-erb-block pos)
+        )
+
+       ((and block-side
+             (string= web-mode-engine "aspx")
+             single-line-block)
+        (web-mode-comment-aspx-block pos)
+        )
+
+       ((and block-side
+             (string= web-mode-engine "jsp")
+             single-line-block)
+        (web-mode-comment-jsp-block pos)
+        )
+
+       ((and block-side
+             (string= web-mode-engine "go")
+             single-line-block)
+        (web-mode-comment-go-block pos)
+        )
+
+       ((and block-side
+             (string= web-mode-engine "php")
+             single-line-block)
+        (web-mode-comment-php-block pos)
+        )
+
+       (t
+
+        (setq ctx (web-mode-point-context
+                   (if mark-active (region-beginning) (line-beginning-position))))
+        ;;        (message "ctx=%S" ctx)
+        (setq language (plist-get ctx :language))
+
+        (if mark-active
+            (setq beg (region-beginning)
+                  end (region-end))
+          (if (string= language "html")
+              (progn
+                (back-to-indentation)
+                (web-mode-element-select))
+            (end-of-line)
+            (set-mark (line-beginning-position))
+            );if
+          (setq beg (region-beginning)
+                end (region-end))
+          ); if mark-active
+
+        (when (> (point) (mark))
+          (exchange-point-and-mark))
+
+        (if (eq (char-before end) ?\n)
+            (setq end (1- end)))
+
+        ;;     (message "language=%S beg=%S end=%S" language beg end)
+        (setq sel (web-mode-trim (buffer-substring-no-properties beg end)))
+        ;;      (message "[language=%s] sel=%s" language sel)
+        (delete-region beg end)
+        (deactivate-mark)
+
+        (cond
+
+         ((string= language "html")
+
+          (cond
+           ((and (= web-mode-comment-style 2) (string= web-mode-engine "django"))
+            (web-mode-insert-and-indent (concat "{# " sel " #}"))
+            )
+           ((and (= web-mode-comment-style 2) (string= web-mode-engine "erb"))
+            (web-mode-insert-and-indent (concat "<%# " sel " %>"))
+            )
+           ((and (= web-mode-comment-style 2) (string= web-mode-engine "aspx"))
+            (web-mode-insert-and-indent (concat "<%-- " sel " --%>"))
+            )
+           ((and (= web-mode-comment-style 2) (string= web-mode-engine "smarty"))
+            (web-mode-insert-and-indent (concat "{* " sel " *}"))
+            )
+           ((and (= web-mode-comment-style 2) (string= web-mode-engine "blade"))
+            (web-mode-insert-and-indent (concat "{{-- " sel " --}}"))
+            )
+           ((and (= web-mode-comment-style 2) (string= web-mode-engine "razor"))
+            (web-mode-insert-and-indent (concat "@* " sel " *@"))
+            )
+           (t
+            (web-mode-insert-and-indent (concat "<!-- " sel " -->"))
+            )
+           )
+
+          )
+
+         ((member language '("php" "javascript" "css"))
+          (web-mode-insert-and-indent (concat "/* " sel " */")))
+
+         ((member language '("erb"))
+          (web-mode-insert-and-indent (replace-regexp-in-string "^" "#" sel)))
+
+         ((member language '("asp"))
+          (web-mode-insert-and-indent (replace-regexp-in-string "^" "''" sel)))
+
+         (t
+          (web-mode-insert-and-indent (concat "/* " sel " */")))
+
+         );cond
+
+        );t
+       );cond
+
+      )))
+
+(defun web-mode-looking-at-pos (regexp pos)
+  "Performs a looking-at at POS."
+  (save-excursion
+    (goto-char pos)
+    (looking-at regexp)
+    ))
+
+(defun web-mode-insert-text-at-pos (text pos)
+  "Insert TEXT at POS."
+  (save-excursion
+    (goto-char pos)
+    (insert text)
+    ))
+
+(defun web-mode-remove-text-at-pos (n pos)
+  "Remove N chars at POS."
+  (delete-region pos (+ pos n))
+  )
+
+(defun web-mode-uncomment-erb-block (pos)
+  "Uncomment an erb block."
+  (let (beg end)
+    (setq beg (web-mode-block-beginning-position pos)
+          end (web-mode-block-end-position pos))
+    (web-mode-remove-text-at-pos 1 (+ beg 2))
+    ))
+
+(defun web-mode-comment-erb-block (pos)
+  "Turn an erb block into a comment block."
+  (let (beg end)
+    (setq beg (web-mode-block-beginning-position pos)
+          end (web-mode-block-end-position pos))
+    (web-mode-insert-text-at-pos "#" (+ beg 2))
+    ))
+
+(defun web-mode-uncomment-django-block (pos)
+  "Uncomment a django block."
+  (let (beg end)
+    (setq beg (web-mode-block-beginning-position pos)
+          end (web-mode-block-end-position pos))
+    (web-mode-remove-text-at-pos 1 (1- end))
+    (web-mode-remove-text-at-pos 1 (1+ beg))
+    ))
+
+(defun web-mode-comment-django-block (pos)
+  "Turn a django block into a comment block."
+  (let (beg end)
+    (setq beg (web-mode-block-beginning-position pos)
+          end (web-mode-block-end-position pos))
+    (web-mode-insert-text-at-pos "#" end)
+    (web-mode-insert-text-at-pos "#" (1+ beg))
+    ))
+
+(defun web-mode-uncomment-dust-block (pos)
+  "Uncomment a dust block."
+  (let (beg end)
+    (setq beg (web-mode-block-beginning-position pos)
+          end (web-mode-block-end-position pos))
+    (web-mode-remove-text-at-pos 1 (1- end))
+    (web-mode-remove-text-at-pos 1 (1+ beg))
+    ))
+
+(defun web-mode-comment-dust-block (pos)
+  "Turn a dust block into a comment block."
+  (let (beg end)
+    (setq beg (web-mode-block-beginning-position pos)
+          end (web-mode-block-end-position pos))
+    (web-mode-insert-text-at-pos "!" end)
+    (web-mode-insert-text-at-pos "!" (1+ beg))
+    ))
+
+(defun web-mode-comment-aspx-block (pos)
+  "Turn a aspx block into a comment block."
+  (let (beg end)
+    (setq beg (web-mode-block-beginning-position pos)
+          end (web-mode-block-end-position pos))
+    (web-mode-insert-text-at-pos "#" end)
+    (web-mode-insert-text-at-pos "#" (1+ beg))
+    ))
+
+(defun web-mode-uncomment-aspx-block (pos)
+  "Uncomment a aspx block."
+  (let (beg end)
+    (setq beg (web-mode-block-beginning-position pos)
+          end (web-mode-block-end-position pos))
+    (web-mode-remove-text-at-pos 1 (1- end))
+    (web-mode-remove-text-at-pos 1 (1+ beg))
+    ))
+
+(defun web-mode-uncomment-jsp-block (pos)
+  "Uncomment a jsp block."
+  (let (beg end)
+    (setq beg (web-mode-block-beginning-position pos)
+          end (web-mode-block-end-position pos))
+    (web-mode-remove-text-at-pos 2 (+ beg 2))
+    ))
+
+(defun web-mode-comment-jsp-block (pos)
+  "Turn a jsp block into a comment block."
+  (let (beg end)
+    (setq beg (web-mode-block-beginning-position pos)
+          end (web-mode-block-end-position pos))
+    (web-mode-insert-text-at-pos "--" (+ beg 2))
+    ))
+
+(defun web-mode-uncomment-go-block (pos)
+  "Uncomment a go block."
+  (let (beg end)
+    (setq beg (web-mode-block-beginning-position pos)
+          end (web-mode-block-end-position pos))
+    (web-mode-remove-text-at-pos 1 (+ beg 2))
+    ))
+
+(defun web-mode-comment-go-block (pos)
+  "Turn a go block into a comment block."
+  (let (beg end)
+    (setq beg (web-mode-block-beginning-position pos)
+          end (web-mode-block-end-position pos))
+    (web-mode-insert-text-at-pos "/" (+ beg 2))
+    ))
+
+(defun web-mode-comment-php-block (pos)
+  "Turn a php block into a comment block."
+  (let (beg end)
+    (setq beg (web-mode-block-beginning-position pos)
+          end (web-mode-block-end-position pos))
+    (web-mode-insert-text-at-pos "*/" (- end 1))
+    (web-mode-insert-text-at-pos "/*" (+ beg (if (web-mode-looking-at-pos "<\\?php" beg) 5 3)))
+    ))
+
+(defun web-mode-uncomment (&optional pos)
+  "Uncomment line(s) at point."
+  (interactive)
+  (unless pos (setq pos (point)))
+  (let ((beg pos)
+        (end pos)
+        (sub2 "")
+        comment prop)
+
+    (cond
+
+     ((and (get-text-property pos 'block-side)
+           (string= web-mode-engine "django"))
+        (web-mode-uncomment-django-block pos)
+        )
+
+     ((and (get-text-property pos 'block-side)
+           (string= web-mode-engine "dust"))
+        (web-mode-uncomment-dust-block pos)
+        )
+
+     ((and (get-text-property pos 'block-side)
+           (string= web-mode-engine "erb"))
+        (web-mode-uncomment-erb-block pos)
+        )
+
+     ((and (get-text-property pos 'block-side)
+           (string= web-mode-engine "aspx"))
+      (web-mode-uncomment-aspx-block pos)
+      )
+
+     ((and (get-text-property pos 'block-side)
+           (string= web-mode-engine "jsp"))
+      (web-mode-uncomment-jsp-block pos)
+      )
+
+     ((and (get-text-property pos 'block-side)
+           (string= web-mode-engine "go"))
+      (web-mode-uncomment-go-block pos)
+      )
+
+     (t
+
+      (if (eq (get-text-property pos 'block-token) 'comment)
+          (setq prop 'block-token)
+        (setq prop 'part-token))
+
+      (if (and (not (bobp))
+               (eq (get-text-property pos prop) (get-text-property (- pos 1) prop)))
+          (setq beg (previous-single-property-change pos prop)))
+
+      (if (and (not (eobp))
+               (eq (get-text-property pos prop) (get-text-property (+ pos 1) prop)))
+          (setq end (next-single-property-change pos prop)))
+
+      ;;    (message "beg(%d) end(%d)" beg end)
+
+      (when (> (- end beg) 4)
+
+        (setq comment (buffer-substring-no-properties beg end))
+        ;;    (message "before[%s]" comment)
+
+        (setq sub2 (substring comment 0 2))
+
+        (cond
+
+         ((member sub2 '("<!" "<%"))
+          (setq comment (replace-regexp-in-string "\\(^<[!%]--[ ]?\\|[ ]?--[%]?>$\\)" "" comment)))
+
+         ((string= sub2 "{#")
+          (setq comment (replace-regexp-in-string "\\(^{#[ ]?\\|[ ]?#}$\\)" "" comment)))
+
+         ((string= sub2 "/*")
+          (setq comment (replace-regexp-in-string "\\(^/\\*[ ]?\\|[ ]?\\*/$\\)" "" comment)))
+
+         ((string= sub2 "//")
+          (setq comment (replace-regexp-in-string "\\(^//\\)" "" comment)))
+
+         )
+
+        ;;    (message "after[%s]" comment)
+
+        (delete-region beg end)
+        (web-mode-insert-and-indent comment)
+        (goto-char beg)
+;;        (back-to-indentation)
+
+        );;when
+
+      ))
+    ))
+
+(defun web-mode-snippet-names ()
+  "Return list a snippet names."
+  (interactive)
+  (let (codes
+        (counter 0)
+        snippet
+        (l (length web-mode-snippets)))
+    (while (< counter l)
+      (setq snippet (nth counter web-mode-snippets))
+      (setq counter (1+ counter))
+      (add-to-list 'codes (list (nth 0 snippet) counter)))
+    ;;    (message "%S" codes)
+    codes))
+
+(defun web-mode-snippet-insert (code)
+  "Insert snippet."
+  (interactive
+   (list (completing-read
+          "Snippet: "
+          (web-mode-snippet-names))))
+  (let (beg
+        (continue t)
+        (counter 0)
+        end
+        sel
+        snippet
+        (l (length web-mode-snippets))
+        pos)
+    (when mark-active
+      (setq sel (web-mode-trim
+                 (buffer-substring-no-properties
+                  (region-beginning) (region-end))))
+      (delete-region (region-beginning) (region-end)))
+    (while (and continue (< counter l))
+      (setq snippet (nth counter web-mode-snippets))
+      (when (string= (nth 0 snippet) code)
+        (setq continue nil))
+      (setq counter (1+ counter)))
+    (when (and (null continue)
+               (nth 1 snippet))
+      (setq beg (point-at-bol))
+      (insert (nth 1 snippet))
+      (setq pos (point))
+      (when sel
+        (insert sel)
+        (setq pos (point)))
+      (if (nth 2 snippet) (insert (nth 2 snippet)))
+      (setq end (point-at-eol))
+      (goto-char pos)
+      (indent-region beg end))
+    ))
+
+(defun web-mode-insert-and-indent (text)
+  "Insert and indent text."
+  (interactive)
+  (let (beg end)
+    (setq beg (point-at-bol))
+    (insert text)
+    (setq end (point-at-eol))
+    (indent-region beg end)))
+
+(defun web-mode-tag-match (&optional pos)
+  "Match tag."
+  (interactive)
+  (unless pos (setq pos (point)))
+  (let (init)
+    (goto-char pos)
+    (setq init (point))
+    (when (> (current-indentation) (current-column))
+      (back-to-indentation))
+    (setq pos (point))
+    (cond
+     ((web-mode-is-comment-or-string)
+      (goto-char init))
+     ((and (get-text-property pos 'block-side)
+           (web-mode-block-beginning)
+           (looking-at-p web-mode-active-block-regexp))
+      (funcall web-mode-engine-control-matcher))
+     ((member (get-text-property pos 'tag-type) '(start end))
+      (web-mode-tag-beginning)
+      (web-mode-match-html-tag))
+     (t
+      (goto-char init))
+     )
+    ))
+
+(defun web-mode-match-html-tag (&optional pos)
+  "Fetch HTML block."
+  (unless pos (setq pos (point)))
+  (let (tag regexp)
+    (setq tag (get-text-property pos 'tag-name))
+    (setq regexp (concat "</?" tag))
+    (if (eq (get-text-property pos 'tag-type) 'end)
+        (web-mode-fetch-html-opening-tag regexp pos)
+      (web-mode-fetch-html-closing-tag regexp pos))
+    t))
+
+(defun web-mode-fetch-html-opening-tag (regexp pos)
+  "Fetch opening HTML block."
+  (let ((counter 1) (n 0))
+    (while (and (> counter 0) (re-search-backward regexp nil t))
+      (when (get-text-property (point) 'tag-beg)
+        (setq n (1+ n))
+        (if (eq (get-text-property (point) 'tag-type) 'end)
+            (setq counter (1+ counter))
+          (setq counter (1- counter))))
+      )
+    (if (= n 0) (goto-char pos))
+    ))
+
+(defun web-mode-fetch-html-closing-tag (regexp pos)
+  "Fetch closing HTML closing block."
+  (let ((counter 1) (n 0))
+    (web-mode-tag-end)
+    (while (and (> counter 0) (re-search-forward regexp nil t))
+      (when (get-text-property (match-beginning 0) 'tag-beg)
+        (setq n (1+ n))
+        (if (eq (get-text-property (point) 'tag-type) 'end)
+            (setq counter (1- counter))
+          (setq counter (1+ counter))))
+      )
+    (if (> n 0)
+        (web-mode-tag-beginning)
+      (goto-char pos))
+    ))
+
+(defun web-mode-match-underscore-block ()
+  "Fetch underscore block."
+  (let (open)
+    (cond
+
+     ((looking-at-p "<%[ ]*}")
+      (search-forward "}")
+      (backward-char)
+      (setq open (web-mode-opening-paren-position))
+      (when open
+        (goto-char open)
+        (web-mode-block-beginning)
+        )
+      )
+
+     ((web-mode-block-ends-with "{[ ]*%>")
+      (web-mode-block-end)
+      (search-backward "{")
+      (setq open (web-mode-closing-paren-position))
+      (when open
+        (goto-char open)
+        (web-mode-block-beginning)
+        )
+      )
+
+     );cond
+
+    ))
+
+
+(defun web-mode-match-php-block ()
+  "Fetch PHP block."
+  (let (regexp match)
+    (cond
+
+     ((looking-at-p "<\\?\\(php\\)?[ ]*}")
+      (let (open)
+        (search-forward "}")
+        (backward-char)
+        (setq open (web-mode-opening-paren-position))
+        (when open
+          (goto-char open)
+          (web-mode-block-beginning)
+          )
+        ))
+
+     ((looking-at-p "<\\?php.+{[ ]*\\?>")
+      (let (close)
+        (web-mode-block-end)
+        (search-backward "{")
+        (setq close (web-mode-closing-paren-position))
+        (when close
+          (goto-char close)
+          (web-mode-block-beginning)
+          )
+        ))
+
+     (t
+      (looking-at web-mode-active-block-regexp)
+      (setq match (match-string-no-properties 3))
+      (setq regexp (concat "<\\?\\(php[ ]+\\|[ ]*\\)?\\(end\\)?\\("
+                         (if (member match '("else" "elseif")) "if" match)
+                         "\\)"))
+      (if (or (string= "end" (match-string-no-properties 2))
+              (member match '("else" "elseif")))
+          (web-mode-fetch-opening-php-block regexp)
+        (web-mode-fetch-closing-php-block regexp))
+      );t
+
+     );cond
+    t))
+
+(defun web-mode-fetch-opening-php-block (regexp)
+  "Fetch PHP opening block."
+  (let ((counter 1))
+    (while (and (> counter 0) (re-search-backward regexp nil t))
+      (if (string= "end" (match-string-no-properties 2))
+          (setq counter (1+ counter))
+        (setq counter (1- counter)))
+      )
+    ))
+
+(defun web-mode-fetch-closing-php-block (regexp)
+  "Fetch PHP closing block."
+  (let ((counter 1))
+    (web-mode-block-end)
+    (while (and (> counter 0) (re-search-forward regexp nil t))
+      (if (string= "end" (match-string-no-properties 2))
+          (setq counter (1- counter))
+        (setq counter (1+ counter))
+        )
+      )
+    (web-mode-block-beginning)
+    ))
+
+(defun web-mode-match-erb-block ()
+  "Fetch ERB block."
+  (let (regexp chunk)
+    (setq chunk (buffer-substring-no-properties (+ (point) 3)
+                                                (- (web-mode-block-end-position) 2)))
+    (setq regexp web-mode-active-block-regexp)
+    (if (string-match-p "else\\|end" chunk)
+        (web-mode-fetch-opening-erb-block regexp)
+      (web-mode-fetch-closing-erb-block regexp))
+    t))
+
+(defun web-mode-fetch-opening-erb-block (regexp)
+  "Fetch erb opening block."
+  (let ((counter 1) match)
+    (while (and (> counter 0) (web-mode-rsb regexp nil t))
+      (setq match (match-string-no-properties 1))
+      (cond
+       ((string= "else" match)
+        )
+       ((not (string= "end" match))
+        (setq counter (1- counter)))
+       (t
+        (setq counter (1+ counter)))
+       )
+      )
+    ))
+
+(defun web-mode-fetch-closing-erb-block (regexp)
+  "Fetch erb closing block."
+  (let ((counter 1) match)
+    (web-mode-block-end)
+    (while (and (> counter 0) (web-mode-rsf regexp nil t))
+      (setq match (match-string-no-properties 1))
+      (cond
+       ((string= "else" match)
+        )
+       ((not (string= "end" match))
+        (setq counter (1+ counter)))
+       (t
+        (setq counter (1- counter)))
+       )
+      )
+    (web-mode-block-beginning)
+    ))
+
+;;tt
+
+(defun web-mode-match-template-toolkit-block ()
+  "Fetch TEMPLATE-TOOLKIT block."
+  (let (regexp chunk)
+    (setq chunk (buffer-substring-no-properties (+ (point) 3)
+                                                (- (web-mode-block-end-position) 2)))
+    (setq regexp web-mode-active-block-regexp)
+    (if (string-match-p "else\\|end\\|END" chunk)
+        (web-mode-fetch-opening-template-toolkit-block regexp)
+      (web-mode-fetch-closing-template-toolkit-block regexp))
+    t))
+
+(defun web-mode-fetch-opening-template-toolkit-block (regexp)
+  "Fetch template-toolkit opening block."
+  (let ((counter 1) match)
+    (while (and (> counter 0) (web-mode-rsb regexp nil t))
+      (setq match (match-string-no-properties 1))
+      (cond
+       ((member match '("else" "ELSE" "elsif" "ELSIF"))
+        )
+       ((not (member match '("end" "END")))
+        (setq counter (1- counter)))
+       (t
+        (setq counter (1+ counter)))
+       )
+      )
+    ))
+
+(defun web-mode-fetch-closing-template-toolkit-block (regexp)
+  "Fetch template-toolkit closing block."
+  (let ((counter 1) match)
+    (web-mode-block-end)
+    (while (and (> counter 0) (web-mode-rsf regexp nil t))
+      (setq match (match-string-no-properties 1))
+      (cond
+       ((member match '("else" "ELSE" "elsif" "ELSIF"))
+        )
+       ((not (member match '("end" "END")))
+        (setq counter (1+ counter)))
+       (t
+        (setq counter (1- counter)))
+       )
+      )
+    (web-mode-block-beginning)
+    ))
+
+
+(defun web-mode-match-blade-block ()
+  "Fetch blade block."
+  (let (beg end match regexp)
+    (looking-at web-mode-active-block-regexp)
+    (setq match (match-string-no-properties 2))
+    (setq regexp (cond
+                  ((member match '("else" "elseif")) "@\\(end\\)?\\(if\\)")
+                  ((string= match "stop") "@\\(section\\|stop\\)")
+                  ((string= match "section") "@\\(endsection\\|stop\\|section\\)")
+                  (t (concat "@\\(end\\)?\\(" match "\\)"))))
+    (if (or (string= "end" (match-string-no-properties 1))
+            (member match '("else" "elseif" "stop")))
+        (web-mode-fetch-opening-blade-block regexp)
+      (web-mode-fetch-closing-blade-block regexp))
+    t))
+
+(defun web-mode-fetch-opening-blade-block (regexp)
+  "Fetch blade opening block."
+  (let ((counter 1))
+    (while (and (> counter 0) (web-mode-rsb regexp nil t))
+      (if (member (match-string-no-properties 1) '("end" "endsection" "stop"))
+          (setq counter (1+ counter))
+        (setq counter (1- counter)))
+      )
+    ))
+
+(defun web-mode-fetch-closing-blade-block (regexp)
+  "Fetch blade closing block."
+  (let ((counter 1))
+    (web-mode-block-end)
+    (while (and (> counter 0) (web-mode-rsf regexp nil t))
+      (if (member (match-string-no-properties 1) '("end" "endsection" "stop"))
+          (setq counter (1- counter))
+        (setq counter (1+ counter)))
+      )
+    (goto-char (match-beginning 0))
+    ))
+
+(defun web-mode-match-django-block ()
+  "Fetch django block."
+  (let (match regexp)
+    (looking-at web-mode-active-block-regexp)
+    (setq match (match-string-no-properties 2))
+    (setq regexp (concat "{%[-]?[ ]+\\(end\\)?\\("
+                         (cond
+                          ((member match '("else" "elseif" "elif")) "if")
+                          ((member match '("empty")) "for")
+                          (t match))
+                         "\\)"))
+    (if (or (string= "end" (match-string-no-properties 1))
+            (member match '("else" "elseif" "elif" "empty")))
+        (web-mode-fetch-opening-django-block regexp)
+      (web-mode-fetch-closing-django-block regexp))
+    t))
+
+(defun web-mode-fetch-opening-django-block (regexp)
+  "Fetch django opening block."
+  (let ((counter 1))
+    (while (and (> counter 0) (web-mode-rsb regexp nil t))
+      (if (string= "end" (match-string-no-properties 1))
+          (setq counter (1+ counter))
+        (setq counter (1- counter)))
+      )
+    ))
+
+(defun web-mode-fetch-closing-django-block (regexp)
+  "Fetch django closing block."
+  (let ((counter 1))
+    (web-mode-block-end)
+    (while (and (> counter 0) (web-mode-rsf regexp nil t))
+      (if (string= "end" (match-string-no-properties 1))
+          (setq counter (1- counter))
+        (setq counter (1+ counter)))
+      )
+    (web-mode-block-beginning)
+    ))
+
+(defun web-mode-match-smarty-block ()
+  "Fetch smarty block."
+  (let (match regexp)
+    (looking-at web-mode-active-block-regexp)
+    (setq match (match-string-no-properties 1))
+    (setq regexp (concat "{/?" (if (string= match "else") "if" match)))
+    (if (or (eq ?\/ (aref (match-string-no-properties 0) 1))
+            (string= match "else"))
+        (web-mode-fetch-opening-smarty-block regexp)
+      (web-mode-fetch-closing-smarty-block regexp))
+    t))
+
+(defun web-mode-fetch-opening-smarty-block (regexp)
+  "Fetch smarty opening block."
+  (let ((counter 1))
+    (while (and (> counter 0) (web-mode-rsb regexp nil t))
+      (if (eq ?\/ (aref (match-string-no-properties 0) 1))
+          (setq counter (1+ counter))
+        (setq counter (1- counter)))
+      )
+    ))
+
+(defun web-mode-fetch-closing-smarty-block (regexp)
+  "Fetch smarty closing block."
+  (let ((counter 1))
+    (web-mode-block-end)
+    (while (and (> counter 0) (web-mode-rsf regexp nil t))
+      (if (eq ?\/ (aref (match-string-no-properties 0) 1))
+          (setq counter (1- counter))
+        (setq counter (1+ counter)))
+      )
+    (web-mode-block-beginning)
+    ))
+
+(defun web-mode-match-dust-block ()
+  "Fetch dust block."
+  (let (match regexp (continue t))
+    (looking-at web-mode-active-block-regexp)
+    (cond
+     ((string= (match-string-no-properties 0) "{:else")
+      (while continue
+        (if (web-mode-block-previous)
+            (when (cdr (web-mode-is-active-block (point)))
+              (setq continue nil))
+          (setq continue nil)
+          )
+        );while
+      )
+     (t
+      (setq match (match-string-no-properties 1))
+      (setq regexp (concat "{[#/:?@><+^]?" match))
+      (if (eq ?\/ (aref (match-string-no-properties 0) 1))
+          (web-mode-fetch-opening-dust-block regexp)
+        (web-mode-fetch-closing-dust-block regexp)))
+     );cond
+    t))
+
+(defun web-mode-fetch-opening-dust-block (regexp)
+  "Fetch dust opening block."
+  (let ((counter 1))
+    (while (and (> counter 0) (web-mode-rsb regexp nil t))
+      (if (eq ?\/ (aref (match-string-no-properties 0) 1))
+          (setq counter (1+ counter))
+        (setq counter (1- counter)))
+      )
+    ))
+
+(defun web-mode-fetch-closing-dust-block (regexp)
+  "Fetch dust closing block."
+  (let ((counter 1))
+    (web-mode-block-end)
+    (while (and (> counter 0) (web-mode-rsf regexp nil t))
+      (if (eq ?\/ (aref (match-string-no-properties 0) 1))
+          (setq counter (1- counter))
+        (setq counter (1+ counter)))
+      )
+    (web-mode-block-beginning)
+    ))
+
+(defun web-mode-match-closure-block ()
+  "Fetch closure block."
+  (let (match regexp (continue t))
+    (looking-at web-mode-active-block-regexp)
+    (cond
+     ((member (match-string-no-properties 0) '("{else" "{elseif"))
+      (while continue
+        (if (web-mode-block-previous)
+            (when (looking-at-p "{if")
+              (setq continue nil))
+          (setq continue nil)
+          )
+        );while
+      )
+     ((member (match-string-no-properties 0) '("{ifempty"))
+      (while continue
+        (if (web-mode-block-previous)
+            (when (looking-at-p "{foreach")
+              (setq continue nil))
+          (setq continue nil)
+          )
+        );while
+      )
+     ((member (match-string-no-properties 0) '("{case" "{default"))
+      (while continue
+        (if (web-mode-block-previous)
+            (when (looking-at-p "{switch")
+              (setq continue nil))
+          (setq continue nil)
+          )
+        );while
+      )
+     (t
+      (setq match (match-string-no-properties 1))
+      (setq regexp (concat "{/?" match))
+      (if (eq ?\/ (aref (match-string-no-properties 0) 1))
+          (web-mode-fetch-opening-closure-block regexp)
+        (web-mode-fetch-closing-closure-block regexp)))
+     );cond
+    t))
+
+(defun web-mode-fetch-opening-closure-block (regexp)
+  "Fetch closure opening block."
+  (let ((counter 1))
+    (while (and (> counter 0) (web-mode-rsb regexp nil t))
+      (if (eq ?\/ (aref (match-string-no-properties 0) 1))
+          (setq counter (1+ counter))
+        (setq counter (1- counter)))
+      )
+    ))
+
+(defun web-mode-fetch-closing-closure-block (regexp)
+  "Fetch closure closing block."
+  (let ((counter 1))
+    (web-mode-block-end)
+    (while (and (> counter 0) (web-mode-rsf regexp nil t))
+      (if (eq ?\/ (aref (match-string-no-properties 0) 1))
+          (setq counter (1- counter))
+        (setq counter (1+ counter)))
+      )
+    (web-mode-block-beginning)
+    ))
+
+
+(defun web-mode-match-velocity-block ()
+  "Fetch velocity block."
+  (let (regexp match)
+    (looking-at web-mode-active-block-regexp)
+    (setq match (match-string-no-properties 1))
+    (setq regexp web-mode-active-block-regexp)
+    (if (member match '("else" "elseif" "end"))
+        (web-mode-fetch-opening-velocity-block regexp)
+      (web-mode-fetch-closing-velocity-block regexp))
+    t))
+
+(defun web-mode-fetch-opening-velocity-block (regexp)
+  "Fetch velocity opening block."
+  (let ((counter 1) match)
+    (while (and (> counter 0) (web-mode-rsb regexp nil t))
+      (setq match (match-string-no-properties 1))
+      (cond
+       ((string= "end" match)
+        (setq counter (1+ counter)))
+       ((string= "else" match)
+        )
+       (t
+        (setq counter (1- counter)))
+       )
+      )
+    ))
+
+(defun web-mode-fetch-closing-velocity-block (regexp)
+  "Fetch velocity closing block."
+  (let ((counter 1) match)
+    (web-mode-block-end)
+    (while (and (> counter 0) (web-mode-rsf regexp nil t))
+      (setq match (match-string-no-properties 1))
+      (cond
+       ((string= "end" match)
+        (setq counter (1- counter)))
+       ((string= "else" match)
+        )
+       (t
+        (setq counter (1+ counter)))
+       )
+      )
+    (goto-char (match-beginning 0))
+    ))
+
+(defun web-mode-match-ctemplate-block ()
+  "Fetch ctemplate block."
+  (let (regexp)
+    (looking-at web-mode-active-block-regexp)
+    (setq regexp (concat "{{[#^/]" (match-string-no-properties 1)))
+    (if (looking-at-p "{{/")
+        (web-mode-fetch-opening-ctemplate-block regexp)
+      (web-mode-fetch-closing-ctemplate-block regexp))
+    t))
+
+(defun web-mode-fetch-opening-ctemplate-block (regexp)
+  "Fetch ctemplate opening block."
+  (let ((counter 1))
+    (while (and (> counter 0) (web-mode-rsb regexp nil t))
+      (if (eq ?\/ (aref (match-string-no-properties 0) 2))
+          (setq counter (1+ counter))
+        (setq counter (1- counter)))
+      )
+    ))
+
+(defun web-mode-fetch-closing-ctemplate-block (regexp)
+  "Fetch ctemplate closing block."
+  (let ((counter 1))
+    (web-mode-block-end)
+    (while (and (> counter 0) (web-mode-rsf regexp nil t))
+      (if (eq ?\/ (aref (match-string-no-properties 0) 2))
+          (setq counter (1- counter))
+        (setq counter (1+ counter)))
+      )
+    (web-mode-block-beginning)
+    ))
+
+(defun web-mode-match-go-block ()
+  "Fetch go block."
+  (let (regexp match)
+    (looking-at web-mode-active-block-regexp)
+    (setq match (match-string-no-properties 1))
+    (setq regexp web-mode-active-block-regexp)
+    (if (member match '("end" "else"))
+        (web-mode-fetch-opening-go-block regexp)
+      (web-mode-fetch-closing-go-block regexp))
+    t))
+
+(defun web-mode-fetch-opening-go-block (regexp)
+  "Fetch go opening block."
+  (let ((counter 1) match)
+    (while (and (> counter 0) (web-mode-rsb regexp nil t))
+      (setq match (match-string-no-properties 1))
+      (cond
+       ((string= "end" match)
+        (setq counter (1+ counter)))
+       ((string= "else" match)
+        )
+       (t
+        (setq counter (1- counter)))
+       )
+      )
+    ))
+
+(defun web-mode-fetch-closing-go-block (regexp)
+  "Fetch go closing block."
+  (let ((counter 1) match)
+    (web-mode-block-end)
+    (while (and (> counter 0) (web-mode-rsf regexp nil t))
+      (setq match (match-string-no-properties 1))
+      (cond
+       ((string= "end" match)
+        (setq counter (1- counter))
+        )
+       ((string= "else" match)
+        )
+       (t
+        (setq counter (1+ counter))
+        )
+       )
+      )
+    (web-mode-block-beginning)
+    ))
+
+(defun web-mode-match-jsp-block ()
+  "Fetch jsp block."
+  (let (regexp)
+    (cond
+     ((looking-at-p "<% }")
+      (let (open)
+        (search-forward "}")
+        (backward-char)
+        (setq open (web-mode-opening-paren-position))
+        (when open
+          (goto-char open)
+          (web-mode-block-beginning))
+        ))
+     (t
+      (looking-at web-mode-active-block-regexp)
+      (setq regexp (concat "<\\(/?" (match-string-no-properties 1) "\\)\\>"))
+      (if (eq ?\/ (aref (match-string-no-properties 0) 1))
+          (web-mode-fetch-opening-jsp-block regexp)
+        (web-mode-fetch-closing-jsp-block regexp)))
+     )
+    t))
+
+(defun web-mode-fetch-opening-jsp-block (regexp)
+  "Fetch jsp opening block."
+  (let ((counter 1))
+    (while (and (> counter 0) (web-mode-rsb regexp nil t))
+      (cond
+       ((eq ?\/ (aref (match-string-no-properties 1) 0))
+        (setq counter (1+ counter)))
+       (t
+        (setq counter (1- counter)))
+       )
+      )
+    ))
+
+(defun web-mode-fetch-closing-jsp-block (regexp)
+  "Fetch jsp closing block."
+  (let ((counter 1))
+    (web-mode-block-end)
+    (while (and (> counter 0) (web-mode-rsf regexp nil t))
+      (cond
+       ((eq ?\/ (aref (match-string-no-properties 1) 0))
+        (setq counter (1- counter)))
+       (t
+        (setq counter (1+ counter)))
+       )
+      )
+    (web-mode-block-beginning)
+    ))
+
+(defun web-mode-match-freemarker-block ()
+  "Fetch freemarker block."
+  (let (regexp match tag char)
+    (looking-at "[<[]/?\\([[:alpha:]]+:[[:alpha:]]+\\|[@#][[:alpha:]._]+\\)")
+    (setq match (match-string-no-properties 0)
+          tag (match-string-no-properties 1)
+          char (if (string= (substring (match-string-no-properties 0) 0 1) "<") "<" "\\["))
+
+    (cond
+     ((member tag '("#else" "#elseif"))
+      (setq match (concat char "/#if")
+            tag "#if")
+      )
+     ((string= tag "#break")
+      (setq match (concat char "/#case")
+            tag "#case"))
+     );cond
+    (setq regexp (concat char "\\(/?" tag "\\)\\>"))
+;;    (message "tag=%S regexp=%S" tag regexp)
+    (if (eq ?\/ (aref match 1))
+        (web-mode-fetch-opening-freemarker-block regexp)
+      (web-mode-fetch-closing-freemarker-block regexp))
+    t))
+
+(defun web-mode-fetch-opening-freemarker-block (regexp)
+  "Fetch freemarker opening block."
+  (let ((counter 1))
+    (while (and (> counter 0) (web-mode-rsb regexp nil t))
+      (cond
+       ((eq ?\/ (aref (match-string-no-properties 1) 0))
+        (setq counter (1+ counter)))
+       (t
+        (setq counter (1- counter)))
+       )
+      )
+    ))
+
+(defun web-mode-fetch-closing-freemarker-block (regexp)
+  "Fetch freemarker closing block."
+  (let ((counter 1))
+    (web-mode-block-end)
+    (while (and (> counter 0) (web-mode-rsf regexp nil t))
+      (cond
+       ((eq ?\/ (aref (match-string-no-properties 1) 0))
+        (setq counter (1- counter)))
+       (t
+        (setq counter (1+ counter)))
+       )
+      )
+    (web-mode-block-beginning)
+    ))
+
+(defun web-mode-element-close ()
+  "Close HTML element."
+  (interactive)
+  (let (jump epp ins tag)
+    (setq epp (web-mode-element-parent-position))
+    (when epp
+      (setq tag (get-text-property epp 'tag-name))
+      (cond
+       ((looking-back "</")
+        (setq ins tag))
+       ((looking-back "<")
+        (setq ins (concat "/" tag)))
+       (t
+        (setq ins (concat "</" tag)))
+       )
+      (unless (looking-at-p "[ ]*>")
+        (setq ins (concat ins ">")))
+      (insert ins)
+      (save-excursion
+        (search-backward "<")
+        (setq jump (looking-back (concat "<" tag ">"))))
+      (when jump
+        (search-backward "<"))
+      );when epp
+    epp
+    ))
+
+(defun web-mode-on-after-change (beg end len)
+  "Handles auto-pairing, auto-closing, and region-refresh after buffer alteration."
+
+;;  (message "pos=%d, beg=%d, end=%d, len=%d, cur=%d" (point) beg end len (current-column))
+;;  (backtrace)
+
+  (setq web-mode-expand-initial-pos nil
+        web-mode-expand-previous-state "")
+
+  (let ((pos (point)) self-insertion chunk auto-closed atomic-insertion)
+
+    (setq atomic-insertion (and (= len 0)
+                                (= 1 (- end beg))))
+
+    (if (not (= (point-max) (+ (buffer-size) 1)))
+
+       (setq web-mode-is-narrowed t)
+
+      ;;-- auto-closing and auto-pairing
+      (when (and (> pos 3)
+                 (not (get-text-property pos 'part-side))
+                 atomic-insertion)
+
+        ;;-- auto-closing
+        (when (and (> web-mode-tag-auto-close-style 0)
+                   (setq chunk (buffer-substring-no-properties (- beg 1) end))
+                   (or (and (= web-mode-tag-auto-close-style 2)
+                            (string-match-p "[[:alnum:]]>" chunk))
+                       (string= "</" chunk)))
+          (when (web-mode-element-close)
+            (setq auto-closed t
+                  self-insertion t))
+          )
+
+        ;;-- auto-pairing
+        (when (and (not web-mode-disable-auto-pairing)
+                   (not self-insertion))
+          (let ((i 0) expr after pos-end (l (length web-mode-auto-pairs)))
+            (setq pos-end (if (> (+ end 10) (line-end-position))
+                              (line-end-position)
+                            (+ end 10)))
+            (setq chunk (buffer-substring-no-properties (- beg 2) end)
+                  after (buffer-substring-no-properties end pos-end))
+            (while (and (< i l) (not self-insertion))
+              (setq expr (elt web-mode-auto-pairs i))
+              (when (string= (elt expr 0) chunk)
+                (unless (string-match-p (elt expr 2) after)
+                  (insert (elt expr 1))
+                  (goto-char (+ pos (elt expr 3)))
+                  (setq self-insertion t))
+                );when
+              (setq i (1+ i))
+              );while
+            );let
+          );when
+
+        );end auto-pairing auto-closing
+
+      ;;-- region-refresh
+      ;;      (save-match-data
+      (cond
+
+       ;; ((and nil (web-mode-is-html-text beg)
+       ;;       atomic-insertion
+       ;;       (not self-insertion)
+       ;;       (not (member (char-before) web-mode-electric-chars)))
+       ;;  (message "no invalidation %c" (char-before))
+       ;;  )
+
+       ((and web-mode-has-any-large-part
+             atomic-insertion
+             (not self-insertion)
+             (or (member (get-text-property beg 'part-language)
+                         '(css
+                           ;;javascript json
+                           ))
+                 (member web-mode-content-type '("css"
+                                                 ;;"javascript" "json"
+                                                 ))))
+        (if (or (string= web-mode-content-type "css")
+                (eq (get-text-property beg 'part-language) 'css))
+            (web-mode-invalidate-css-region beg end)
+          (web-mode-invalidate-javascript-region beg end))
+        )
+
+       ((and nil
+             web-mode-has-any-large-block
+             atomic-insertion
+             (not self-insertion)
+             (get-text-property beg 'block-side)
+             (member web-mode-engine '("asp")))
+        (web-mode-invalidate-asp-region beg end)
+        )
+
+       (t
+        (web-mode-scan-region (or (web-mode-previous-tag-at-bol-pos beg)
+                                  (point-min))
+                              (or (web-mode-next-tag-at-eol-pos end)
+                                  (point-max))))
+       )
+      ;;        );save-match-data
+
+      ;;-- auto-indentation
+      (when (and (not web-mode-disable-auto-indentation)
+                 (or auto-closed
+                     (and (> end (point-min))
+                          (get-text-property (1- end) 'tag-end)
+                          (get-text-property (line-beginning-position) 'tag-beg))))
+        (indent-for-tab-command)
+        )
+
+      );if narrowed
+    ))
+
+(defun web-mode-invalidate-css-region (pos-beg pos-end)
+  "Invalidate css region (only when one char has been inserted)"
+  (save-excursion
+    (let (pair part-beg part-end)
+      (if (string= web-mode-content-type "css")
+          (setq part-beg (point-min)
+                part-end (point-max))
+        (setq part-beg (web-mode-part-beginning-position pos-beg)
+              part-end (web-mode-part-end-position pos-beg)))
+      (setq pair (web-mode-css-current-rule pos-beg part-beg part-end))
+;;      (message "css region : %S > %S" (car pair) (cdr pair))
+      (web-mode-scan-region (car pair) (cdr pair) "css")
+      )))
+
+(defun web-mode-invalidate-javascript-region (pos-beg pos-end)
+  "Invalidate javascript region (only when one char has been inserted)"
+  (save-excursion
+    (let (beg end part-beg part-end lang is-token-char)
+      (goto-char pos-beg)
+      (setq is-token-char (not (null (member (char-before) '(?\" ?\' ?\/ ?\< ?\*)))))
+;;      (message "%S %c(%S)" pos-beg (char-before) is-token-char)
+      (if (member web-mode-content-type '("javascript" "json"))
+          (setq part-beg (point-min)
+                part-end (point-max)
+                lang web-mode-content-type)
+        (setq part-beg (web-mode-part-beginning-position pos-beg)
+              part-end (web-mode-part-end-position pos-beg)
+              lang (symbol-name (get-text-property pos-beg 'part-language))))
+      (cond
+       ((and (not is-token-char)
+             (get-text-property (1- pos-beg) 'part-token))
+;;        (message "nothing")
+        )
+       ((and (not is-token-char)
+             (progn (back-to-indentation) (setq beg (point)))
+             (if (>= beg part-beg) beg part-beg)
+             (progn (goto-char pos-end) (end-of-line) (setq end (point)))
+             (if (<= end part-end) end part-end))
+        ;;            (message "%S" (buffer-substring-no-properties beg end))
+        (web-mode-scan-part beg end lang)
+        )
+       ;;        (message "%S" (buffer-substring-no-properties part-beg part-end))
+       (t
+        (web-mode-scan-part part-beg part-end lang))
+       )
+      )))
+
+;; todo : gestion du remove-text-properties (ne pas toucher à pas mal de properties : block-beg, part-side etc.)
+(defun web-mode-invalidate-asp-region (pos-beg pos-end)
+  "Invalidate asp region."
+  (save-excursion
+    (let (beg end part-beg part-end)
+      (setq part-beg (web-mode-block-beginning-position pos-beg)
+            part-end (web-mode-block-end-position pos-beg))
+      (if (and part-beg part-end
+               (progn (goto-char pos-beg) t)
+               (not (member (char-after) '(?\" ?\' ?\/)))
+               (progn (back-to-indentation) t)
+               (setq beg (point))
+               (if (>= beg part-beg) beg part-beg)
+               (progn (goto-char pos-end) t)
+               (progn (end-of-line) t)
+               (setq end (point))
+               (if (<= end part-end) end part-end))
+            (web-mode-scan-region beg end "asp")
+        (web-mode-scan-region part-beg part-end "asp")
+        )
+      )))
+
+(defun web-mode-apostrophes-replace ()
+  "Replace ' with ’."
+  (interactive)
+  (save-excursion
+    (let ((min (point-min)) (max (point-max)))
+      (when mark-active
+        (setq min (region-beginning)
+              max (region-end))
+        (deactivate-mark))
+      (goto-char min)
+      (while (web-mode-rsf-content "\\([[:alpha:]]\\)'\\([[:alpha:]]\\)" max)
+        (replace-match "\\1’\\2")
+        );while
+      )))
+
+(defun web-mode-entities-replace ()
+  "Replace HTML entities ie. &eacute; becomes é"
+  (interactive)
+  (save-excursion
+    (let (name pair (min (point-min)) (max (point-max)))
+      (when mark-active
+        (setq min (region-beginning)
+              max (region-end))
+        (deactivate-mark))
+      (goto-char min)
+      (while (web-mode-rsf-content "&\\([[:alpha:]]\\{2,8\\}\\);" max)
+        (setq name (match-string 1))
+        (setq pair (assoc name web-mode-html-entities))
+;;        (message "pos=%S name=%S pair=%S" (point) name pair)
+        (when pair
+          (replace-match (cdr pair)))
+        );while
+      )))
+
+(defun web-mode-xml-replace ()
+  "Replace &, > and < in HTML content."
+  (interactive)
+  (save-excursion
+    (let (expr (min (point-min)) (max (point-max)))
+      (when mark-active
+        (setq min (region-beginning)
+              max (region-end))
+        (deactivate-mark))
+      (goto-char min)
+      (while (web-mode-rsf-content "[&<>]" max)
+        (replace-match (cdr (assq (char-before) web-mode-xml-chars)) t t))
+      )))
+
+(defun web-mode-quotes-replace ()
+  "Replace dumb quotes."
+  (interactive)
+  (save-excursion
+    (let (expr (min (point-min)) (max (point-max)))
+      (when mark-active
+        (setq min (region-beginning)
+              max (region-end))
+        (deactivate-mark))
+      (goto-char min)
+      (setq expr (concat (car web-mode-smart-quotes) "\\2" (cdr web-mode-smart-quotes)))
+      (while (web-mode-rsf-content "\\(\"\\)\\(.\\{1,200\\}\\)\\(\"\\)" max)
+        (replace-match expr)
+        );while
+      )))
+
+(defun web-mode-xpath (&optional pos)
+  "HTML path"
+  (interactive)
+  (unless pos (setq pos (point)))
+  (save-excursion
+    (goto-char pos)
+    (let (path)
+      (while (web-mode-element-parent (point))
+        (setq path (cons (get-text-property (point) 'tag-name) path))
+        )
+      (message "/%s" (mapconcat 'identity path "/"))
+      )))
+
+(defun web-mode-block-ends-with (regexp)
+  "Check if current ends with regexp"
+  (save-excursion
+    (and (web-mode-block-end)
+         (looking-back regexp))
+    ))
+
+;;-- position -----------------------------------------------------------------------
+
+(defun web-mode-opening-paren-position (&optional pos limit)
+  "Fetch opening paren."
+  (save-restriction
+    ;;    (unless paren (setq paren "("))
+    (unless pos (setq pos (point)))
+    (unless limit (setq limit nil))
+    (goto-char pos)
+    (let ((continue t)
+          (n -1)
+          block-side
+          paren
+          (pairs '((")" . "[)(]")
+                   ("]" . "[\]\[]")
+                   ("}" . "[}{]")))
+          pt
+          regexp)
+      (setq paren (string (char-after)))
+      ;;      (message "paren=%S" paren)
+      (setq regexp (cdr (assoc paren pairs)))
+      (if (null regexp) (setq continue nil))
+      (setq block-side (get-text-property pos 'block-side))
+      (while (and continue (re-search-backward regexp limit t))
+        (unless (or (web-mode-is-comment-or-string)
+                    (and block-side (not (get-text-property (point) 'block-side))))
+          ;;          (message "pos=%S pt=%S" pos (point))
+          (if (not (string= (string (char-after)) paren))
+              (progn
+                (setq n (1+ n))
+                (if (= n 0)
+                    (setq continue nil
+                          pt (point))))
+            (setq n (1- n)))
+          ;;          (message "n=%S" n)
+          );unless
+        )
+      pt
+      )))
+
+(defun web-mode-closing-paren-position (&optional pos limit)
+  "Fetch opening paren."
+  (save-excursion
+    (unless pos (setq pos (point)))
+    (unless limit (setq limit nil))
+    (goto-char pos)
+    (let ((continue t)
+          paren
+          (n 0)
+          (pairs '(("(" . "[)(]")
+                   ("[" . "[\]\[]")
+                   ("{" . "[}{]")))
+          pt
+          block-side
+          regexp)
+      (setq paren (string (char-after)))
+      (setq regexp (cdr (assoc paren pairs)))
+      (if (null regexp) (setq continue nil))
+      (setq block-side (get-text-property pos 'block-side))
+      (while (and continue (re-search-forward regexp limit t))
+        (unless (or (web-mode-is-comment-or-string)
+                    (and block-side (not (get-text-property (point) 'block-side))))
+          ;;          (message "char-before=%S pt=%S" (string (char-before)) (point))
+          (if (string= (string (char-before)) paren)
+              (setq n (1+ n))
+            (setq n (1- n))
+            (when (= n 0)
+              (setq continue nil
+                    pt (1- (point))))
+            )
+          ;;        (message "pt=%S char=%S n=%S" (point) (string (char-before)) n)
+          )
+        )
+      ;;      (message "n=%S pt=%S" n pt)
+      pt
+      )))
+
+(defun web-mode-opening-paren-block-position (pos limit)
+  "Is opened code line."
+  (save-excursion
+    (goto-char pos)
+    (let (c
+          n
+          pt
+          (continue t)
+          (pairs '((")" . "(")
+                   ("]" . "[")
+                   ("}" . "{")))
+          (h (make-hash-table :test 'equal))
+          (regexp "[\]\[)(}{]"))
+      (while (and continue (re-search-backward regexp limit t))
+        (unless (web-mode-is-comment-or-string)
+          (setq c (string (char-after)))
+          (cond
+           ((member c '("(" "{" "["))
+            (setq n (gethash c h 0))
+            (if (= n 0)
+                (setq continue nil
+                      pt (point))
+              (puthash c (1+ n) h)
+              ))
+           (t
+            (setq c (cdr (assoc c pairs)))
+            (setq n (gethash c h 0))
+            (puthash c (1- n) h))
+           );cond
+          );unless
+        );while
+      ;;      (message "h=%S pt=%S" h pt)
+      pt
+      )))
+
+(defun web-mode-previous-tag-at-bol-pos (pos)
+  "Line beginning with and HTML tag. BOL is returned or nil."
+  (save-excursion
+    (goto-char pos)
+    (setq pos nil)
+    (let ((continue t))
+      (back-to-indentation)
+      (if (get-text-property (point) 'tag-beg)
+          (setq pos (line-beginning-position))
+        (while continue
+          (forward-line -1)
+          (setq pos (point))
+          (when (bobp)
+            (setq continue nil))
+          (back-to-indentation)
+          (if (get-text-property (point) 'tag-beg)
+              (setq continue nil)
+            (setq pos nil))
+          );while
+        );if
+      pos)))
+
+(defun web-mode-next-tag-at-eol-pos (pos)
+  "Line ending with an HTML tag. EOL is returned or nil."
+  (save-excursion
+    (goto-char pos)
+    (let ((continue t))
+      (while continue
+        (end-of-line)
+        (setq pos (point))
+        (when (eobp)
+          (setq continue nil))
+        (skip-chars-backward " ")
+        (if (and (> (point) (point-min))
+                 (get-text-property (1- (point)) 'tag-end))
+            (setq continue nil)
+          (setq pos nil))
+        (if continue (forward-line))
+        );while
+      pos)))
+
+(defun web-mode-tag-match-position (&optional pos)
+  "Match tag position."
+  (unless pos (setq pos (point)))
+  (save-excursion
+    (web-mode-tag-match pos)
+    (if (= pos (point)) nil (point))))
+
+(defun web-mode-tag-beginning-position (&optional pos)
+  "Beginning position of the current tag. POINT is at <."
+  (unless pos (setq pos (point)))
+  (let (beg)
+    (cond
+     ((get-text-property pos 'tag-beg)
+      (setq beg pos))
+     ((get-text-property pos 'tag-name)
+      (setq beg (1- (previous-single-property-change pos 'tag-beg)))
+      (when (not (get-text-property beg 'tag-beg))
+        (setq beg nil)))
+     (t
+      (setq beg nil))
+     );cond
+    beg))
+
+(defun web-mode-tag-end-position (&optional pos)
+  "End position of the current tag. POINT is at >."
+  (unless pos (setq pos (point)))
+  (let (end)
+    (cond
+     ((get-text-property pos 'tag-end)
+      (setq end pos))
+     ((get-text-property pos 'tag-name)
+      (setq end (next-single-property-change pos 'tag-end))
+      (when (not (get-text-property end 'tag-end))
+        (setq end nil)))
+     (t
+      (setq end nil))
+     );cond
+    end))
+
+(defun web-mode-part-end-position (&optional pos)
+  "End position of the current part."
+  (unless pos (setq pos (point)))
+  (cond
+   ((member web-mode-content-type '("css" "javascript" "json"))
+    (setq pos (point-max)))
+   ((not (get-text-property pos 'part-side))
+    (setq pos nil))
+   (t
+    (setq pos (next-single-property-change pos 'tag-beg))
+    (if (not (get-text-property pos 'tag-beg))
+        (setq pos nil)
+      (setq pos (1- pos)))
+    )
+   );cond
+  pos)
+
+(defun web-mode-part-beginning-position (&optional pos)
+  "Beginning of pat"
+  (unless pos (setq pos (point)))
+  (cond
+   ((member web-mode-content-type '("css" "javascript" "json"))
+    (setq pos (point-min)))
+   ((not (get-text-property pos 'part-side))
+    (setq pos nil))
+   (t
+    (setq pos (previous-single-property-change pos 'tag-end))
+    (when (or (= pos (point-min))
+              (not (get-text-property (1- pos) 'tag-end)))
+      (setq pos nil)))
+   );cond
+  pos)
+
+(defun web-mode-element-beginning-position (&optional pos)
+  "Beginning of element pos."
+  (unless pos (setq pos (point)))
+  (cond
+   ((null (get-text-property pos 'tag-type))
+    (setq pos (web-mode-element-parent-position)))
+   ((eq (get-text-property pos 'tag-type) 'end)
+    (setq pos (web-mode-tag-match-position pos))
+    (setq pos (if (get-text-property pos 'tag-beg) pos nil)))
+   ((member (get-text-property pos 'tag-type) '(start void))
+    (setq pos (web-mode-tag-beginning-position pos)))
+   (t
+    (setq pos nil))
+   );cond
+  pos)
+
+(defun web-mode-element-end-position (&optional pos)
+  "End of element pos."
+  (unless pos (setq pos (point)))
+  (cond
+   ((null (get-text-property pos 'tag-type))
+    (setq pos (web-mode-element-parent-position pos))
+    (when pos
+      (setq pos (web-mode-tag-match-position pos))
+      (when pos (setq pos (web-mode-tag-end-position pos)))
+      )
+    )
+   ((member (get-text-property pos 'tag-type) '(end void))
+    (setq pos (web-mode-tag-end-position pos))
+    )
+   ((member (get-text-property pos 'tag-type) '(start))
+    (setq pos (web-mode-tag-match-position pos))
+    (when pos (setq pos (web-mode-tag-end-position pos))))
+   (t
+    (setq pos nil))
+   );cond
+  pos)
+
+(defun web-mode-element-child-position (&optional pos)
+  "Child element pos."
+  (save-excursion
+    (let (child close)
+      (unless pos (setq pos (point)))
+      (goto-char pos)
+      (cond
+       ((eq (get-text-property pos 'tag-type) 'start)
+        (web-mode-match-html-tag)
+        (setq close (point))
+        (goto-char pos)
+        )
+       ((eq (get-text-property pos 'tag-type) 'void)
+        )
+       ((eq (get-text-property pos 'tag-type) 'end)
+        (web-mode-tag-beginning)
+        (setq close (point))
+        (web-mode-match-html-tag)
+        )
+       ((web-mode-element-parent-position pos)
+        (setq pos (point))
+        (web-mode-match-html-tag)
+        (setq close (point))
+        (goto-char pos)
+        )
+       );cond
+      (when (and close
+                 (web-mode-element-next)
+                 (< (point) close))
+        (setq child (point))
+        )
+      child
+      )))
+
+(defun web-mode-element-parent-position (&optional pos)
+  "Parent element pos."
+  (let (n
+        tag-type
+        tag-name
+        (continue t)
+        (h (make-hash-table :test 'equal)))
+    (save-excursion
+      (if pos (goto-char pos))
+      (while (and continue (web-mode-tag-previous))
+        (setq pos (point))
+        (setq tag-type (get-text-property pos 'tag-type)
+              tag-name (get-text-property pos 'tag-name))
+        (setq n (gethash tag-name h 0))
+        (when (member tag-type '(end start))
+          (if (eq tag-type 'end)
+              (puthash tag-name (1- n) h)
+            (puthash tag-name (1+ n) h)
+            (when (= n 0) (setq continue nil))
+            );if
+          );when
+        );while
+      );save-excursion
+    (if (null continue) pos nil)
+    ))
+
+(defun web-mode-block-beginning-position (&optional pos)
+  "web-mode-block-beginning-position"
+  (unless pos (setq pos (point)))
+;;  (message "web-mode-block-beginning-position=%S" pos)
+  (cond
+   ((or (and (get-text-property pos 'block-side)
+             (= pos (point-min)))
+        (get-text-property pos 'block-beg))
+    )
+   ((and (> pos (point-min))
+         (get-text-property (1- pos) 'block-beg))
+    (setq pos (1- pos))
+    )
+   ((get-text-property pos 'block-side)
+    (setq pos (previous-single-property-change pos 'block-beg))
+    (setq pos (if pos (1- pos) (point-min)))
+;;    (setq pos (if pos pos (point-min)))
+    )
+   (t
+    (setq pos nil))
+   );cond
+;;  (message "web-mode-block-beginning-position=%S" pos)
+  pos)
+
+(defun web-mode-block-end-position (&optional pos)
+  "web-mode-block-end-position"
+  (unless pos (setq pos (point)))
+  (cond
+   ((get-text-property pos 'block-end)
+    )
+   ((get-text-property pos 'block-side)
+    (setq pos (or (next-single-property-change pos 'block-end)
+                  (point-max)))
+    )
+   (t
+    (setq pos nil))
+   );cond
+  pos)
+
+(defun web-mode-block-previous-position (&optional pos)
+  "web-mode-block-previous-position"
+  (unless pos (setq pos (point)))
+  (cond
+   ((get-text-property pos 'block-side)
+    (setq pos (web-mode-block-beginning-position pos))
+    (when (and pos (> pos (point-min)))
+      (setq pos (1- pos))
+      (while (and (> pos (point-min))
+                  (eq (char-after pos) ?\n))
+        (setq pos (1- pos))
+        )
+      ;;            (message "pos=%S  <%c>" pos (char-after pos))
+      (if (get-text-property pos 'block-side)
+          (setq pos (web-mode-block-beginning-position pos))
+        (setq pos (previous-single-property-change pos 'block-side))
+        (when (and pos (> pos (point-min)))
+          (setq pos (web-mode-block-beginning-position (1- pos))))
+        );if
+      );when
+    )
+   (t
+    (setq pos (previous-single-property-change pos 'block-side))
+    (when (and pos (> pos (point-min)))
+      (setq pos (web-mode-block-beginning-position (1- pos))))
+    )
+   );conf
+  pos)
+
+(defun web-mode-block-next-position (&optional pos)
+  "web-mode-block-next-position"
+  (unless pos (setq pos (point)))
+  (if (get-text-property pos 'block-side)
+      (if (= pos (point-min))
+          (set pos (point-min))
+        (setq pos (web-mode-block-end-position pos))
+        (when (and pos (> (point-max) pos))
+          (setq pos (1+ pos))
+          (if (not (get-text-property pos 'block-side))
+              (setq pos (next-single-property-change pos 'block-side)))
+          );when
+        )
+    (setq pos (next-single-property-change pos 'block-side)))
+  pos)
+
+;;--- /positions
+
+;;--- nav
+
+(defun web-mode-tag-beginning (&optional pos)
+  "Fetch html tag beg."
+  (interactive)
+  (unless pos (setq pos (point)))
+  (setq pos (web-mode-tag-beginning-position pos))
+  (when pos (goto-char pos))
+  pos)
+
+(defun web-mode-tag-end (&optional pos)
+  "Fetch html tag end."
+  (interactive)
+  (unless pos (setq pos (point)))
+  (setq pos (web-mode-tag-end-position pos))
+  (when pos
+    (setq pos (1+ pos))
+    (goto-char pos))
+  pos)
+
+(defun web-mode-tag-previous (&optional pos)
+  "Fetch previous tag."
+  (interactive)
+  (unless pos (setq pos (point)))
+  (if (bobp)
+      (setq pos nil)
+    (when (get-text-property pos 'tag-beg)
+      (setq pos (1- pos)))
+    (setq pos (previous-single-property-change pos 'tag-beg))
+    (when pos
+      (setq pos (1- pos))
+      (goto-char pos))
+    )
+  pos)
+
+(defun web-mode-tag-next (&optional pos)
+  "Fetch next tag. Might be HTML comment or server tag (ie. JSP)."
+  (interactive)
+  (unless pos (setq pos (point)))
+  (if (eobp)
+      (setq pos nil)
+    (when (get-text-property pos 'tag-beg)
+      (setq pos (1+ pos)))
+    (setq pos (next-single-property-change pos 'tag-beg))
+    (when pos (goto-char pos)))
+  pos)
+
+(defun web-mode-element-previous ()
+  "Fetch previous element."
+  (interactive)
+  (let (continue ret (pos (point)) (props '(start void)))
+    (setq continue (not (bobp)))
+    (while continue
+      (setq ret (web-mode-tag-previous))
+      (when (or (null ret)
+                (member (get-text-property (point) 'tag-type) props))
+        (setq continue nil)
+        )
+      );while
+    (unless ret (goto-char pos))
+    ret))
+
+(defun web-mode-element-next ()
+  "Fetch next element."
+  (interactive)
+  (let (continue ret (pos (point)) (props '(start void)))
+    (setq continue (not (eobp)))
+    (while continue
+      (setq ret (web-mode-tag-next))
+      (when (or (null ret)
+                (member (get-text-property (point) 'tag-type) props))
+        (setq continue nil)
+        )
+      );while
+    (unless ret (goto-char pos))
+    ret))
+
+(defun web-mode-element-sibling-next ()
+  "Fetch next element."
+  (interactive)
+  (let (parent ret (pos (point)))
+    (save-excursion
+      (cond
+       ((not (get-text-property pos 'tag-type))
+        (when (and (web-mode-element-parent)
+                   (web-mode-match-html-tag)
+                   (web-mode-element-next))
+          (setq ret (point))
+          )
+        )
+       ((eq (get-text-property pos 'tag-type) 'start)
+        (when (and (web-mode-match-html-tag)
+                   (web-mode-element-next))
+          (setq ret (point))
+          )
+        )
+       (t
+        (when (web-mode-element-next)
+          (setq ret (point))
+          )
+        )
+       );cond
+
+      );save
+    (if ret (goto-char ret))
+    ))
+
+
+(defun web-mode-element-beginning (&optional pos)
+  "Move to beginning of element."
+  (interactive)
+  (unless pos (setq pos (point)))
+  (setq pos (web-mode-element-beginning-position pos))
+  (when pos (goto-char pos))
+  pos)
+
+(defun web-mode-element-end (&optional pos)
+  "Move to end of element."
+  (interactive)
+  (unless pos (setq pos (point)))
+  (setq pos (web-mode-element-end-position pos))
+  (when pos
+    (setq pos (1+ pos))
+    (goto-char pos))
+  pos)
+
+(defun web-mode-element-parent (&optional pos)
+  "Fetch parent element."
+  (interactive)
+  (unless pos (setq pos (point)))
+  (setq pos (web-mode-element-parent-position pos))
+  (when pos (goto-char pos))
+  pos)
+
+(defun web-mode-element-child (&optional pos)
+  "Fetch child element."
+  (interactive)
+  (unless pos (setq pos (point)))
+  (setq pos (web-mode-element-child-position pos))
+  (when pos (goto-char pos))
+  pos)
+
+(defun web-mode-element-traverse ()
+  "Traverse html dom tree."
+  (interactive)
+  (cond
+   ((web-mode-element-child)
+    )
+   ((web-mode-element-sibling-next)
+    )
+   ((web-mode-element-parent)
+    (unless (web-mode-element-sibling-next)
+      (goto-char (point-min)))
+    )
+   );cond
+  )
+
+(defun web-mode-block-previous (&optional pos)
+  "web-mode-prev-server-block"
+  (interactive)
+  (unless pos (setq pos (point)))
+  (setq pos (web-mode-block-previous-position pos))
+  (when pos (goto-char pos))
+  pos)
+
+(defun web-mode-block-next (&optional pos)
+  "web-mode-next-server-block"
+  (interactive)
+  (unless pos (setq pos (point)))
+  (setq pos (web-mode-block-next-position pos))
+  (when pos (goto-char pos))
+  pos)
+
+(defun web-mode-block-beginning (&optional pos)
+  "web-mode-block-beg"
+  (interactive)
+  (unless pos (setq pos (point)))
+  (setq pos (web-mode-block-beginning-position pos))
+  (when pos (goto-char pos))
+  pos)
+
+(defun web-mode-block-end (&optional pos)
+  "web-mode-block-beg"
+  (interactive)
+  (unless pos (setq pos (point)))
+  (setq pos (web-mode-block-end-position pos))
+  (when pos
+    (setq pos (1+ pos))
+    (goto-char pos))
+  pos)
+
+;;--- /nav ----------------------------------------------------------------------
+
+;;--- search
+
+(defun web-mode-rsf-balanced (regexp-open regexp-close &optional limit noerror)
+  "web-mode-rsf-balanced in client."
+  (unless noerror (setq noerror t))
+  (let ((continue t)
+        (level 1)
+        ret
+        (regexp (concat regexp-open "\\|" regexp-close)))
+;;    (message "regexp=%S" regexp)
+    (while continue
+      (setq ret (re-search-forward regexp limit noerror))
+;;      (message "regexp=%S ret=%S pos=%S" regexp ret (point))
+      (cond
+       ((null ret)
+        (setq continue nil)
+        )
+       (t
+;;        (message "%S" (match-string-no-properties 0))
+        (if (string-match-p regexp-open (match-string-no-properties 0))
+            (setq level (1+ level))
+          (setq level (1- level)))
+        (when (< level 1)
+          (setq continue nil)
+          )
+        );t
+       );cond
+      );while
+    ret))
+
+(defun web-mode-sb-client (regexp &optional limit noerror)
+  "search-backward in client."
+  (unless noerror (setq noerror t))
+  (let ((continue t) ret)
+    (while continue
+      (setq ret (search-backward regexp limit noerror))
+      (if (or (null ret)
+              (not (get-text-property (point) 'block-side)))
+          (setq continue nil))
+      )
+    ret))
+
+(defun web-mode-rsb-client (regexp &optional limit noerror)
+  "re-search-backward in client."
+  (unless noerror (setq noerror t))
+  (let ((continue t) ret)
+    (while continue
+      (setq ret (re-search-backward regexp limit noerror))
+      (if (or (null ret)
+              (not (get-text-property (point) 'block-side)))
+          (setq continue nil))
+      )
+    ret))
+
+(defun web-mode-rsf-client (regexp &optional limit noerror)
+  "re-search-forward in client."
+  (unless noerror (setq noerror t))
+  (let ((continue t) ret)
+    (while continue
+      (setq ret (re-search-forward regexp limit noerror))
+      (if (or (null ret)
+              (not (get-text-property (match-beginning 0) 'block-side)))
+          (setq continue nil))
+      );while
+    ret))
+
+(defun web-mode-sf-client (expr &optional limit noerror)
+  "search-forward in client."
+  (unless noerror (setq noerror t))
+  (let ((continue t) ret)
+    (while continue
+      (setq ret (search-forward expr limit noerror))
+      (if (or (null ret)
+              (not (get-text-property (- (point) (length expr)) 'block-side)))
+          (setq continue nil))
+      )
+    ret))
+
+(defun web-mode-rsb (regexp &optional limit noerror)
+  "re-search-backward not in comment or string."
+  (unless noerror (setq noerror t))
+  (let ((continue t) ret)
+    (while continue
+      (setq ret (re-search-backward regexp limit noerror))
+      (if (or (null ret)
+              (not (web-mode-is-comment-or-string)))
+          (setq continue nil)))
+    ret))
+
+(defun web-mode-rsf (regexp &optional limit noerror)
+  "re-search-forward not in comment or string."
+  (unless noerror (setq noerror t))
+  (let ((continue t) ret)
+    (while continue
+      (setq ret (re-search-forward regexp limit noerror))
+      (if (or (null ret)
+              (not (web-mode-is-comment-or-string)))
+          (setq continue nil))
+      )
+    ret))
+
+(defun web-mode-sb (expr &optional limit noerror)
+  "re-search-backward not in comment or string."
+  (unless noerror (setq noerror t))
+  (let ((continue t) ret)
+    (while continue
+      (setq ret (search-backward expr limit noerror))
+      (if (or (null ret)
+              (not (web-mode-is-comment-or-string)))
+          (setq continue nil)))
+    ret))
+
+(defun web-mode-sf (expr &optional limit noerror)
+  "re-search-backward not in comment or string."
+  (unless noerror (setq noerror t))
+  (let ((continue t) ret)
+    (while continue
+      (setq ret (search-forward expr limit noerror))
+      (if (or (null ret)
+              (not (web-mode-is-comment-or-string)))
+          (setq continue nil)))
+    ret))
+
+(defun web-mode-rsb-html (regexp &optional limit noerror)
+  "re-search-backward only in html."
+  (unless noerror (setq noerror t))
+  (let ((continue t) ret)
+    (while continue
+      (setq ret (re-search-backward regexp limit noerror))
+      (if (or (null ret)
+              (not (web-mode-is-part-token-or-server)))
+          (setq continue nil)))
+    ret))
+
+(defun web-mode-rsf-html (regexp &optional limit noerror)
+  "re-search-forward only in html."
+  (unless noerror (setq noerror t))
+  (let ((continue t) ret)
+    (while continue
+      (setq ret (re-search-forward regexp limit noerror))
+      (if (or (null ret)
+              (not (web-mode-is-part-token-or-server)))
+          (setq continue nil)))
+    ret))
+
+(defun web-mode-rsf-content (regexp &optional limit noerror)
+  "re-search-forward only in html content."
+  (unless noerror (setq noerror t))
+  (let ((continue t) ret beg end)
+    (while continue
+      (setq ret (re-search-forward regexp limit noerror)
+            beg (if (null ret) (point) (match-beginning 0))
+            end (if (null ret) (point) (match-end 0)))
+;;      (message "pt=%S" pos)
+      (if (or (null ret)
+              (and (web-mode-is-html-text beg)
+                   (web-mode-is-html-text end)))
+          (setq continue nil)))
+    ret))
+
+(defun web-mode-is-html-tag (&optional pos)
+  "Is point in an html tag."
+  (unless pos (setq pos (point)))
+  (member (get-text-property pos 'tag-type) '(start end void)))
+
+(defun web-mode-is-comment-or-string-line ()
+  "Detect if current line is in a comment or in a string."
+  (save-excursion
+    (let ((continue t) (counter 0))
+      (beginning-of-line)
+      (while (and continue (not (eolp)))
+        (if (web-mode-is-comment-or-string)
+            (setq counter (1+ counter))
+          (when (not (eq ?\s (following-char)))
+            (setq continue nil
+                  counter 0))
+          );if
+        (forward-char)
+        );while
+      (> counter 0)
+      )))
+
+(defun web-mode-is-part-token-or-server (&optional pos)
+  "Detect if POS is in a comment, a string or in server script."
+  (unless pos (setq pos (point)))
+  (or (get-text-property pos 'block-side)
+      (not (null (member (get-text-property pos 'part-token) '(string comment))))))
+
+(defun web-mode-is-part-token-line ()
+  "Detect if current line has only client tokens (string/comment) or server blocks."
+  (save-excursion
+    (let ((continue t) (counter 0))
+      (beginning-of-line)
+      (while (and continue (not (eolp)))
+        (if (web-mode-is-part-token-or-server)
+            (setq counter (1+ counter))
+          (when (not (eq ?\s (following-char)))
+            (setq continue nil
+                  counter 0))
+          );if
+        (forward-char)
+        );while
+      (> counter 0)
+      )))
+
+(defun web-mode-is-html-text (&optional pos)
+  "Is point in a html text."
+  (unless pos (setq pos (point)))
+  (not (or (get-text-property pos 'part-side)
+           (get-text-property pos 'tag-type)
+           (get-text-property pos 'block-side)
+           )))
+
+(defun web-mode-is-comment-or-string (&optional pos)
+  "Detect if point is in a comment or in a string."
+  (unless pos (setq pos (point)))
+  (or (memq (get-text-property pos 'block-token) '(string comment))
+      (memq (get-text-property pos 'part-token) '(string comment))))
+
+(defun web-mode-is-comment (&optional pos)
+  "Detect if point is in a comment."
+  (unless pos (setq pos (point)))
+  (or (eq (get-text-property pos 'block-token) 'comment)
+      (eq (get-text-property pos 'part-token) 'comment)))
+
+;;--- end search
+
+(defun web-mode-reload ()
+  "Reload web-mode."
+  (interactive)
+  (web-mode-with-silent-modifications
+   (setq web-mode-time nil)
+   (put-text-property (point-min) (point-max) 'invisible nil)
+   (remove-overlays)
+   (unload-feature 'web-mode)
+   (setq web-mode-disable-css-colorization t)
+   (web-mode)
+   (if (fboundp 'web-mode-hook)
+       (web-mode-hook))))
+
+(defun web-mode-trace (msg)
+  "Benchmark."
+  (interactive)
+  (when nil
+    (when (null web-mode-time) (setq web-mode-time (current-time)))
+    (setq sub (time-subtract (current-time) web-mode-time))
+    (message "%18s: time elapsed = %Ss %9Sµs" msg (nth 1 sub) (nth 2 sub))
+    ))
+
+(provide 'web-mode)
+
+;;; web-mode.el ends here
+
+
+;; ;;todo: a supprimer
+;; (defun web-mode-tag-previous2 (&optional regexp)
+;;   "Fetch previous tag."
+;;   (interactive)
+;;   (unless regexp (setq regexp web-mode-tag-regexp))
+;;   (let ((continue t) ret)
+;;     (while continue
+;;       (setq ret (re-search-backward regexp nil t))
+;;       (if (or (null ret)
+;;               (get-text-property (point) 'tag-beg))
+;;           (setq continue nil))
+;;       );while
+;;     ret))
+;; ;;todo : a supprimer
+;; (defun web-mode-element-previous2 ()
+;;   "Fetch previous element."
+;;   (interactive)
+;;   (web-mode-tag-previous "<[[:alpha:]]"))
+
+
+;; (defvar web-mode-django-filters
+;;   (eval-when-compile
+;;     (regexp-opt
+;;      '("add" "addslashes" "capfirst" "center" "cut"
+;;        "date" "default" "default_if_none" "dictsort"
+;;        "dictsortreversed" "divisibleby"
+;;        "escape" "escapejs" "filesizeformat" "first"
+;;        "fix_ampersands" "floatformat"
+;;        "force_escape" "format_integer" "format_number"
+;;        "get_digit" "humanize" "iriencode" "join"
+;;        "last" "length" "length_is" "linebreaks" "linebreaksbr" "linenumbers"
+;;        "ljust" "lower" "make_list"
+;;        "phonenumeric" "pluralize" "pprint"
+;;        "random" "random_num" "random_range" "removetags" "rjust"
+;;        "safe" "safeseq" "slice" "slugify" "stringformat" "striptags"
+;;        "time" "timesince" "timeuntil" "title" "trans" "truncatechars" "truncatewords"
+;;        "truncatewords_html" "unordered_list" "upper" "urlencode"
+;;        "urlize" "urlizetrunc"
+;;        "wordcount" "wordwrap" "yesno")))
+;;   "Django filters.")
diff --git a/scripts/emacs/web-mode-master/wfs-mode.el b/scripts/emacs/web-mode-master/wfs-mode.el
new file mode 100644
index 0000000000000000000000000000000000000000..49cc9eb7d9f438ab0bcb3d50c383949cc37acb14
--- /dev/null
+++ b/scripts/emacs/web-mode-master/wfs-mode.el
@@ -0,0 +1,128 @@
+;;; wfs-mode.el --- minor mode for accessing files by http
+
+;; Copyright 2013 François-Xavier Bois
+
+;; Version: 0.0.1
+;; Author: François-Xavier Bois <fxbois AT Google Mail Service>
+;; Maintainer: François-Xavier Bois
+;; Created: August 2013
+;; Keywords: files http network
+
+;; =========================================================================
+;; This work is sponsored by Kernix : Digital Agency (Web & Mobile) in Paris
+;; =========================================================================
+
+;; This file is not part of Emacs
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;; Code goes here
+
+(defgroup wfs nil
+  "web fs."
+  :group 'comm
+  :group 'files
+  :version "0.0.1")
+
+(defcustom wfs-verbose nil
+  "Verbosity."
+  :group 'wfs
+  :type 'boolean)
+
+(defcustom wfs-repo-alist nil
+  "List of repositories."
+  :group 'wfs
+  :type 'list)
+
+(defvar wfs-repo nil)
+
+(defun wfs-repo-names ()
+  "Repo names."
+;;  (interactive)
+  (let ((names '("scopalto" "titi<")))
+    names
+    ))
+
+(defun wfs-connect (repo)
+  "connect to a repo."
+  (interactive
+   (list (completing-read
+          "Repo: "
+          (wfs-repo-names))))
+;;  (message "repo=%S" repo)
+  (setq wfs-repo repo)
+  )
+
+(defun wfs-url-get (url)
+  "url get"
+  (with-current-buffer (url-retrieve-synchronously "http://localhost")
+    (goto-char (point-min))
+    (re-search-forward "^$")
+    (forward-char)
+    (buffer-substring-no-properties (point) (point-max)))
+  )
+
+(defun wfs-open ()
+  "open remote file."
+  (interactive)
+  (unless wfs-repo
+    (call-interactively 'wfs-connect))
+  (unless wfs-repo
+    (error "select a repo"))
+  (let (name buffer enable-local-variables magic-mode-alist)
+    (setq name (concat "wsf://" wfs-repo "/www/test.psp"))
+    (setq buffer (get-buffer name))
+    (if buffer
+        (switch-to-buffer buffer)  
+      (setq buffer (get-buffer-create name))
+      (switch-to-buffer buffer)
+      (with-silent-modifications
+        (insert (wfs-url-get "http://localhost"))
+        (set-visited-file-name "www-test.psp")
+;;        (message "%S" (buffer-file-name))
+        (set-auto-mode)
+        (rename-buffer name)
+        ;;      (set-visited-file-name nil)
+        ;;      (web-mode)
+        )
+;;      (not-modified)
+      );if
+    );let
+  )
+
+(defun wfs-save ()
+  "save local buffer to remote file."
+  (interactive))
+
+(defun wfs-reload ()
+  "Reload wfs-mode."
+  (interactive)
+  (unload-feature 'wfs-mode)
+  (wfs-mode)
+  (when (fboundp 'wfs-mode-hook)
+      (wfs-mode-hook))
+  (message "wfs is reloaded")
+  )
+
+(define-minor-mode wfs-mode
+  "web fs."
+  ;;(wfs-connect)
+  )
+
+
+(provide 'wfs-mode)
+
+;;; wfs-mode.el ends here