Subject: Re: bug#35381: 26.2; nxml-mode doesn't fontify attributes in single quotes

From: Stefan Monnier <[email-masked]>
Date: Tue, 23 Apr 2019 12:09:19 -0400

> In an nxml-mode buffer, put the following text:
>
> <x a="foo" b='bar'/>
>
> Only "foo" is fontified in as a string, while bar is not.

IIRC this is technically correct because IIRC in XML (contrary to SGML)
only "..."  is allowed and not '...'.  Don't take my word for it, tho,
it's just a vague recollection.

This said, it's probably a good idea to understand '...' in nxml-mode,
since there are various circumstances where you may want to use
nxml-mode to edit files in a format that's more permissive than strict XML.

> This is a regression since Emacs 25.3.

Even more reason to allow '...'.
Have you investigated the source of the regression?

> The patch below seems solves problem, though I'm not entirely sure
> about it: there are some confusing comments in sgml-mode.el about
> drawbacks and tradeoffs of recognizing single quotes that I'm not
> really following (are they applicable to SGML only, and not XML?).

IIRC the comments aren't related to the issue of accepting '...' itself,
but to some of the side-effects of doing it naively in cases such as

    <em>That's right!</em>

but we're no so naive any more, so I believe that we can support this
without the downsides.

> There's also the difference that attribute values are now fontified with
> font-lock-string-face rather than nxml-attribute-value, though I'm not
> sure that's worth fixing.

I don't see where else font-lock-string-face would be used in nxml-mode,
so I see no need to use a special face like nxml-attribute-value for
attributed values.

> +(defun nxml-syntax-propertize (start end)
> +  "Syntactic keywords for `nxml-mode'."
> +  (goto-char start)
> +  (sgml-syntax-propertize-inside end)
> +  (funcall
> +   (syntax-propertize-rules
> +    sgml-syntax-propertize-rules
> +    ;; Like the " rule in `sgml-syntax-propertize-rules', but for '.
> +    ("'" (0 (if (prog1 (zerop (car (syntax-ppss (match-beginning 0))))
> +                  (goto-char (match-end 0)))
> +                (string-to-syntax ".")))))
> +   start end))
> +
> +(defconst nxml-tag-syntax-table
> +  (let ((table (make-syntax-table sgml-tag-syntax-table)))
> +    (modify-syntax-entry ?\' "\"'" table))
> +  "Syntax table used to parse XML tags.")
> +
>  ;;;###autoload
>  (define-derived-mode nxml-mode text-mode "nXML"
>    ;; We use C-c C-i instead of \\[nxml-balanced-close-start-tag-inline]
> @@ -517,8 +535,8 @@ (define-derived-mode nxml-mode text-mode "nXML"
>        (with-silent-modifications
>  	(nxml-with-invisible-motion
>  	  (nxml-scan-prolog)))))
> -  (setq-local syntax-ppss-table sgml-tag-syntax-table)
> -  (setq-local syntax-propertize-function #'sgml-syntax-propertize)
> +  (setq-local syntax-ppss-table nxml-tag-syntax-table)
> +  (setq-local syntax-propertize-function #'nxml-syntax-propertize)

Hmm... I think it would be better to change `sgml-syntax-propertize` so
it does what we need.  After all, it's more important to support '...'
for SGML  than for XML.

        Stefan