]> code.delx.au - gnu-emacs/blobdiff - lisp/textmodes/sgml-mode.el
Merge from origin/emacs-24
[gnu-emacs] / lisp / textmodes / sgml-mode.el
index b72887720342fb98caf3945e534e265126e76bf7..fbcc0ede7aa55d306ffb87173094526f67c7e2d5 100644 (file)
@@ -1,10 +1,10 @@
 ;;; sgml-mode.el --- SGML- and HTML-editing modes -*- coding: utf-8 -*-
 
-;; Copyright (C) 1992, 1995-1996, 1998, 2001-2013 Free Software
+;; Copyright (C) 1992, 1995-1996, 1998, 2001-2014 Free Software
 ;; Foundation, Inc.
 
 ;; Author: James Clark <jjc@jclark.com>
-;; Maintainer: FSF
+;; Maintainer: emacs-devel@gnu.org
 ;; Adapted-By: ESR, Daniel Pfeiffer <occitan@esperanto.org>,
 ;;             F.Potorti@cnuce.cnr.it
 ;; Keywords: wp, hypermedia, comm, languages
   :type 'integer
   :group 'sgml)
 
+(defcustom sgml-xml-mode nil
+  "When non-nil, tag insertion functions will be XML-compliant.
+It is set to be buffer-local when the file has
+a DOCTYPE or an XML declaration."
+  :type 'boolean
+  :version "22.1"
+  :group 'sgml)
+
 (defcustom sgml-transformation-function 'identity
   "Default value for `skeleton-transformation-function' in SGML mode."
   :type 'function
+  :initialize 'custom-initialize-default
+  :set (lambda (sym val)
+         (set-default sym val)
+         (mapc (lambda (buff)
+                 (with-current-buffer buff
+                   (and (derived-mode-p 'sgml-mode)
+                        (not sgml-xml-mode)
+                        (setq skeleton-transformation-function val))))
+               (buffer-list)))
   :group 'sgml)
 
 (put 'sgml-transformation-function 'variable-interactive
@@ -223,12 +240,21 @@ This takes effect when first loading the `sgml-mode' library.")
   "A table for mapping non-ASCII characters into SGML entity names.
 Currently, only Latin-1 characters are supported.")
 
-;; nsgmls is a free SGML parser in the SP suite available from
-;; ftp.jclark.com and otherwise packaged for GNU systems.
-;; Its error messages can be parsed by next-error.
-;; The -s option suppresses output.
-
-(defcustom sgml-validate-command "nsgmls -s" ; replaced old `sgmls'
+(defcustom sgml-validate-command
+  ;; prefer tidy because (o)nsgmls is often built without --enable-http
+  ;; which makes it next to useless
+  (cond ((executable-find "tidy")
+         ;; tidy is available from http://tidy.sourceforge.net/
+         "tidy --gnu-emacs yes -utf8 -e -q")
+        ((executable-find "nsgmls")
+         ;; nsgmls is a free SGML parser in the SP suite available from
+         ;; ftp.jclark.com, replaced old `sgmls'.
+         "nsgmls -s")
+        ((executable-find "onsgmls")
+         ;; onsgmls is the community version of `nsgmls'
+         ;; hosted on http://openjade.sourceforge.net/
+         "onsgmls -s")
+        (t "Install (o)nsgmls, tidy, or some other SGML validator, and set `sgml-validate-command'"))
   "The command to validate an SGML document.
 The file name of current buffer file name will be appended to this,
 separated by a space."
@@ -295,8 +321,8 @@ Any terminating `>' or `/' is not matched.")
 
 (defconst sgml-syntax-propertize-function
   (syntax-propertize-rules
-  ;; Use the `b' style of comments to avoid interference with the -- ... --
-  ;; comments recognized when `sgml-specials' includes ?-.
+   ;; Use the `b' style of comments to avoid interference with the -- ... --
+   ;; comments recognized when `sgml-specials' includes ?-.
   ;; FIXME: beware of <!--> blabla <!--> !!
    ("\\(<\\)!--" (1 "< b"))
     ("--[ \t\n]*\\(>\\)" (1 "> b"))
@@ -305,7 +331,7 @@ Any terminating `>' or `/' is not matched.")
     ;; going to change, so as not to need to flush the data we just computed.
     ("\"" (0 (if (prog1 (zerop (car (syntax-ppss (match-beginning 0))))
                    (goto-char (match-end 0)))
-                 "."))))
+           (string-to-syntax ".")))))
   "Syntactic keywords for `sgml-mode'.")
 
 ;; internal
@@ -364,14 +390,6 @@ an optional alist of possible values."
                       (string :tag "Description")))
   :group 'sgml)
 
-(defcustom sgml-xml-mode nil
-  "When non-nil, tag insertion functions will be XML-compliant.
-It is set to be buffer-local when the file has
-a DOCTYPE or an XML declaration."
-  :type 'boolean
-  :version "22.1"
-  :group 'sgml)
-
 (defvar sgml-empty-tags nil
   "List of tags whose !ELEMENT definition says EMPTY.")
 
@@ -438,6 +456,9 @@ This function is designed for use in `fill-nobreak-predicate'.
         (skip-chars-backward "/?!")
         (eq (char-before) ?<))))
 
+(defvar tildify-space-string)
+(defvar tildify-foreach-region-function)
+
 ;;;###autoload
 (define-derived-mode sgml-mode text-mode '(sgml-xml-mode "XML" "SGML")
   "Major mode for editing SGML documents.
@@ -459,6 +480,27 @@ Do \\[describe-key] on the following bindings to discover what they do.
 \\{sgml-mode-map}"
   (make-local-variable 'sgml-saved-validate-command)
   (make-local-variable 'facemenu-end-add-face)
+  ;; If encoding does not allow non-break space character, use reference.
+  ;; FIXME: Perhaps use &nbsp; if possible (e.g. when we know its HTML)?
+  (setq-local tildify-space-string
+              (if (equal (decode-coding-string
+                          (encode-coding-string " " buffer-file-coding-system)
+                          buffer-file-coding-system) " ")
+                  " " "&#160;"))
+  ;; FIXME: Use the fact that we're parsing the document already
+  ;; rather than using regex-based filtering.
+  (setq-local tildify-foreach-region-function
+              (apply-partially
+               'tildify-foreach-ignore-environments
+               `((,(eval-when-compile
+                     (concat
+                      "<\\("
+                      (regexp-opt '("pre" "dfn" "code" "samp" "kbd" "var"
+                                    "PRE" "DFN" "CODE" "SAMP" "KBD" "VAR"))
+                      "\\)\\>[^>]*>"))
+                  . ("</" 1 ">"))
+                 ("<! *--" . "-- *>")
+                 ("<" . ">"))))
   ;;(make-local-variable 'facemenu-remove-face-function)
   ;; A start or end tag by itself on a line separates a paragraph.
   ;; This is desirable because SGML discards a newline that appears
@@ -635,10 +677,8 @@ This only works for Latin-1 input."
 (define-skeleton sgml-tag
   "Prompt for a tag and insert it, optionally with attributes.
 Completion and configuration are done according to `sgml-tag-alist'.
-If you like tags and attributes in uppercase do \\[set-variable]
-`skeleton-transformation-function' RET `upcase' RET, or put this
-in your `.emacs':
-  (setq sgml-transformation-function 'upcase)"
+If you like tags and attributes in uppercase, customize
+`sgml-transformation-function' to 'upcase."
   (funcall (or skeleton-transformation-function 'identity)
            (setq sgml-tag-last
                 (completing-read