diff options
| author | Noam Postavsky | 2019-04-21 22:44:50 -0400 |
|---|---|---|
| committer | Noam Postavsky | 2019-05-09 06:42:40 -0400 |
| commit | 7dab3ee7ab54b3c2e7bc24170376054786c01d6f (patch) | |
| tree | 73b562aa6b3588215949f1ed4773e58b21d18dfd | |
| parent | e4cde42657f8f91f795e6b7041dc50b896dc468d (diff) | |
| download | emacs-7dab3ee7ab54b3c2e7bc24170376054786c01d6f.tar.gz emacs-7dab3ee7ab54b3c2e7bc24170376054786c01d6f.zip | |
Recognize single quote attribute values in nxml and sgml (Bug#35381)
* lisp/textmodes/sgml-mode.el (sgml-specials): Add single quote.
(sgml-syntax-propertize-rules): Handle single quote.
* test/lisp/nxml/nxml-mode-tests.el (nxml-mode-font-lock-quotes): New
test.
* test/lisp/textmodes/sgml-mode-tests.el
(sgml-delete-tag-bug-8203-should-not-delete-apostrophe): Now passes.
| -rw-r--r-- | lisp/textmodes/sgml-mode.el | 34 | ||||
| -rw-r--r-- | test/lisp/nxml/nxml-mode-tests.el | 20 | ||||
| -rw-r--r-- | test/lisp/textmodes/sgml-mode-tests.el | 1 |
3 files changed, 35 insertions, 20 deletions
diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el index 50b2077ef4f..128e58810e5 100644 --- a/lisp/textmodes/sgml-mode.el +++ b/lisp/textmodes/sgml-mode.el | |||
| @@ -100,24 +100,20 @@ a DOCTYPE or an XML declaration." | |||
| 100 | :group 'sgml | 100 | :group 'sgml |
| 101 | :type 'hook) | 101 | :type 'hook) |
| 102 | 102 | ||
| 103 | ;; As long as Emacs's syntax can't be complemented with predicates to context | 103 | ;; The official handling of "--" is complicated in SGML, and |
| 104 | ;; sensitively confirm the syntax of characters, we have to live with this | 104 | ;; historically not well supported by browser HTML parsers. |
| 105 | ;; kludgy kind of tradeoff. | 105 | ;; Recommendations for writing HTML comments is to use <!--...--> |
| 106 | (defvar sgml-specials '(?\") | 106 | ;; (where ... doesn't contain "--") to avoid the complications |
| 107 | ;; altogether (XML goes even further by requiring this in the spec). | ||
| 108 | ;; So there is probably no need to handle it "correctly". | ||
| 109 | (defvar sgml-specials '(?\" ?\') | ||
| 107 | "List of characters that have a special meaning for SGML mode. | 110 | "List of characters that have a special meaning for SGML mode. |
| 108 | This list is used when first loading the `sgml-mode' library. | 111 | This list is used when first loading the `sgml-mode' library. |
| 109 | The supported characters and potential disadvantages are: | 112 | The supported characters are ?\\\", ?\\=', and ?-. |
| 110 | 113 | ||
| 111 | ?\\\" Makes \" in text start a string. | 114 | Including ?- makes double dashes into comment delimiters, but |
| 112 | ?\\=' Makes \\=' in text start a string. | 115 | they are really only supposed to delimit comments within DTD |
| 113 | ?- Makes -- in text start a comment. | 116 | definitions. So we normally turn it off.") |
| 114 | |||
| 115 | When only one of ?\\\" or ?\\=' are included, \"\\='\" or \\='\"\\=', as can be found in | ||
| 116 | DTDs, start a string. To partially avoid this problem this also makes these | ||
| 117 | self insert as named entities depending on `sgml-quick-keys'. | ||
| 118 | |||
| 119 | Including ?- has the problem of affecting dashes that have nothing to do | ||
| 120 | with comments, so we normally turn it off.") | ||
| 121 | 117 | ||
| 122 | (defvar sgml-quick-keys nil | 118 | (defvar sgml-quick-keys nil |
| 123 | "Use <, >, &, /, SPC and `sgml-specials' keys \"electrically\" when non-nil. | 119 | "Use <, >, &, /, SPC and `sgml-specials' keys \"electrically\" when non-nil. |
| @@ -351,12 +347,12 @@ Any terminating `>' or `/' is not matched.") | |||
| 351 | ("--[ \t\n]*\\(>\\)" (1 "> b")) | 347 | ("--[ \t\n]*\\(>\\)" (1 "> b")) |
| 352 | ("\\(<\\)[?!]" (1 (prog1 "|>" | 348 | ("\\(<\\)[?!]" (1 (prog1 "|>" |
| 353 | (sgml-syntax-propertize-inside end)))) | 349 | (sgml-syntax-propertize-inside end)))) |
| 354 | ;; Double quotes outside of tags should not introduce strings. | 350 | ;; Quotes outside of tags should not introduce strings. |
| 355 | ;; Be careful to call `syntax-ppss' on a position before the one we're | 351 | ;; Be careful to call `syntax-ppss' on a position before the one we're |
| 356 | ;; going to change, so as not to need to flush the data we just computed. | 352 | ;; going to change, so as not to need to flush the data we just computed. |
| 357 | ("\"" (0 (if (prog1 (zerop (car (syntax-ppss (match-beginning 0)))) | 353 | ("[\"']" (0 (if (prog1 (zerop (car (syntax-ppss (match-beginning 0)))) |
| 358 | (goto-char (match-end 0))) | 354 | (goto-char (match-end 0))) |
| 359 | (string-to-syntax "."))))))) | 355 | (string-to-syntax "."))))))) |
| 360 | 356 | ||
| 361 | (defun sgml-syntax-propertize (start end) | 357 | (defun sgml-syntax-propertize (start end) |
| 362 | "Syntactic keywords for `sgml-mode'." | 358 | "Syntactic keywords for `sgml-mode'." |
diff --git a/test/lisp/nxml/nxml-mode-tests.el b/test/lisp/nxml/nxml-mode-tests.el index 57a731ad182..92744be619d 100644 --- a/test/lisp/nxml/nxml-mode-tests.el +++ b/test/lisp/nxml/nxml-mode-tests.el | |||
| @@ -58,5 +58,25 @@ | |||
| 58 | (nxml-balanced-close-start-tag-inline) | 58 | (nxml-balanced-close-start-tag-inline) |
| 59 | (should (equal (buffer-string) "<a><b c=\"\"></b></a>")))) | 59 | (should (equal (buffer-string) "<a><b c=\"\"></b></a>")))) |
| 60 | 60 | ||
| 61 | (ert-deftest nxml-mode-font-lock-quotes () | ||
| 62 | (with-temp-buffer | ||
| 63 | (nxml-mode) | ||
| 64 | (insert "<x a=\"dquote attr\" b='squote attr'>\"dquote text\"'squote text'</x>") | ||
| 65 | (font-lock-ensure) | ||
| 66 | (let ((squote-txt-pos (search-backward "squote text")) | ||
| 67 | (dquote-txt-pos (search-backward "dquote text")) | ||
| 68 | (squote-att-pos (search-backward "squote attr")) | ||
| 69 | (dquote-att-pos (search-backward "dquote attr"))) | ||
| 70 | ;; Just make sure that each quote uses the same face for quoted | ||
| 71 | ;; attribute values, and a different face for quoted text | ||
| 72 | ;; outside tags. Don't test `font-lock-string-face' vs | ||
| 73 | ;; `nxml-attribute-value' here. | ||
| 74 | (should (equal (get-text-property squote-att-pos 'face) | ||
| 75 | (get-text-property dquote-att-pos 'face))) | ||
| 76 | (should (equal (get-text-property squote-txt-pos 'face) | ||
| 77 | (get-text-property dquote-txt-pos 'face))) | ||
| 78 | (should-not (equal (get-text-property squote-txt-pos 'face) | ||
| 79 | (get-text-property dquote-att-pos 'face)))))) | ||
| 80 | |||
| 61 | (provide 'nxml-mode-tests) | 81 | (provide 'nxml-mode-tests) |
| 62 | ;;; nxml-mode-tests.el ends here | 82 | ;;; nxml-mode-tests.el ends here |
diff --git a/test/lisp/textmodes/sgml-mode-tests.el b/test/lisp/textmodes/sgml-mode-tests.el index 20b5e27ff5d..7318a667b36 100644 --- a/test/lisp/textmodes/sgml-mode-tests.el +++ b/test/lisp/textmodes/sgml-mode-tests.el | |||
| @@ -125,7 +125,6 @@ The point is set to the beginning of the buffer." | |||
| 125 | (should (string= content (buffer-string)))))) | 125 | (should (string= content (buffer-string)))))) |
| 126 | 126 | ||
| 127 | (ert-deftest sgml-delete-tag-bug-8203-should-not-delete-apostrophe () | 127 | (ert-deftest sgml-delete-tag-bug-8203-should-not-delete-apostrophe () |
| 128 | :expected-result :failed | ||
| 129 | (sgml-with-content | 128 | (sgml-with-content |
| 130 | "<title>Winter is comin'</title>" | 129 | "<title>Winter is comin'</title>" |
| 131 | (sgml-delete-tag 1) | 130 | (sgml-delete-tag 1) |