Subject: bug#43511: 27.1; [PATCH] Files with lowercase doctype are not in mhtml-mode by default

From: Daniel Martín <[email-masked]>
Date: Sat, 19 Sep 2020 16:35:14 +0200

This is a regression caused by the fix for bug 36401.

Steps to reproduce:

emacs -Q
M-x browse-url-emacs RET https://www.gnu.org/software/emacs/ RET

Expected results:

The HTML contents of the Emacs website are shown, and the buffer is in
mhtml-mode.

Actual results:

The HTML contents of the Emacs website are shown, but the buffer is in
fundamental-mode.

The proposed solution to accomodate both wanted behaviors is to extend
the regular expression to cover a "DOCTYPE" in a case-insensitive
way. The standard says that's also supported:
https://html.spec.whatwg.org/multipage/syntax.html#the-doctype

I've attached a patch with the proposed solution, on top of
emacs-27. Let me know if you'd want to apply it on top of master
instead.

Thanks.

>From aeaa1e3f8f3f68ec28488664ed2d507288f0e97d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Mart=C3=ADn?= <[email-masked]>
Date: Sat, 19 Sep 2020 16:18:50 +0200
Subject: [PATCH] Put files in mhtml-mode when they have <!DOCTYPE,
 case-insensitive

This regressed after the fix for Bug#36401 was applied.

* lisp/files.el (magic-fallback-mode-alist): Match "DOCTYPE" in a
case-insensitive way before putting files in mhtml-mode. See
https://html.spec.whatwg.org/multipage/syntax.html#the-doctype for the
standard reference.
* test/lisp/files-tests.el (files-test-magic-mode-alist-doctype): Add
a test.
---
 lisp/files.el            |  2 +-
 test/lisp/files-tests.el | 12 ++++++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/lisp/files.el b/lisp/files.el
index 3e4ad7c0d4..7fd98607b7 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -3058,7 +3058,7 @@ magic-fallback-mode-alist
 		"\\(?:!DOCTYPE[ \t\r\n]+[^>]*>[ \t\r\n]*<[ \t\r\n]*" comment-re "*\\)?"
 		"[Hh][Tt][Mm][Ll]"))
      . mhtml-mode)
-    ("<!DOCTYPE[ \t\r\n]+[Hh][Tt][Mm][Ll]" . mhtml-mode)
+    ("<![Dd][Oo][Cc][Tt][Yy][Pp][Ee][ \t\r\n]+[Hh][Tt][Mm][Ll]" . mhtml-mode)
     ;; These two must come after html, because they are more general:
     ("<\\?xml " . xml-mode)
     (,(let* ((incomment-re "\\(?:[^-]\\|-[^-]\\)")
diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el
index ac56a7732f..b67268cd0f 100644
--- a/test/lisp/files-tests.el
+++ b/test/lisp/files-tests.el
@@ -1326,5 +1326,17 @@ files-tests-file-attributes-equal
       (normal-mode)
       (should (not (eq major-mode 'text-mode))))))
 
+(ert-deftest files-test-magic-mode-alist-doctype ()
+  "Test that DOCTYPE and variants put files in mhtml-mode."
+  (with-temp-buffer
+    (goto-char (point-min))
+    (insert "<!DOCTYPE html>")
+    (normal-mode)
+    (should (eq major-mode 'mhtml-mode))
+    (erase-buffer)
+    (insert "<!doctype html>")
+    (normal-mode)
+    (should (eq major-mode 'mhtml-mode))))
+
 (provide 'files-tests)
 ;;; files-tests.el ends here
-- 
2.28.0