Subject: bug#75928: closed (Re: bug#75928: 31.0.50; `dom-print' often fails to print an SVG DOM)

From: [email-masked] (GNU bug Tracking System)
Date: Sat, 15 Feb 2025 11:51:02 +0000

Your bug report

#75928: 31.0.50; `dom-print' often fails to print an SVG DOM

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
75928: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=75928
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#75928: 31.0.50; `dom-print' often fails to print an SVG DOM
From: Eli Zaretskii <[email-masked]>
To: David Ponce <[email-masked]>
Cc: [email-masked]
Date: Sat, 15 Feb 2025 13:50:45 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

> Date: Sat, 8 Feb 2025 13:55:16 +0100
> Cc: [email-masked]
> From: David Ponce <[email-masked]>
> 
> On 2025-02-08 10:41, Eli Zaretskii wrote:
> >> Date: Wed, 5 Feb 2025 13:01:04 +0100
> >> From:  David Ponce via "Bug reports for GNU Emacs,
> >>   the Swiss army knife of text editors" <[email-masked]>
> >>
> >> I attached a new patch that also avoid printing attributes without a
> >> value (value is nil in the DOM).
> >>
> >> I also refreshed the list of HTML boolean attributes from the current
> >> standard, and put checking for a boolean attribute in a separate
> >> inline function for clarity.
> >>
> >> The patch also slightly improve the code by computing the indentation
> >> column outside of loop and delegating indentation to `indent-line-to'.
> > 
> > Thanks.
> > 
> > Using indent-line-to requires binding indent-tabs-mode to nil, to make
> > sure we produce spaces and not TABs, right?
> > 
> > Also, please make sure the dom.el test suite still passes after this
> > change, if you haven't already.  Bonus points for providing a new test
> > for this feature.
> 
> Hello Eli,
> 
> Thank you very much for your feedback.
> 
> Please, find attached a new patch to force indent with spaces and to add
> two new tests to dom-tests.el.

Thanks, installed on the master branch, and closing the bug.

Subject: 31.0.50; `dom-print' often fails to print an SVG DOM
From: David Ponce <[email-masked]>
To: [email-masked]
Date: Wed, 29 Jan 2025 16:52:28 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

Hello,

Currently `dom-print' is mostly unusable to print an SVG DOM because it
fails as soon as it encounters an attribute value which is not a string.
This is unfortunate, because `dom-print' can be very useful for
examining a DOM by pretty-printing it.

Here is a simple example that illustrates the problem:

(require 'svg)
(let ((svg (svg-create 100 100)))
   (svg-rectangle svg 0 0 "100%" "100%" :fill "blue")
   (svg-text svg "A text" :x 0 :y 55 :stroke "yellow" :fill "yellow")
   (dom-print svg t t))

Which produce this backtrace when evaluated in the *scratch* buffer:

Debugger entered--Lisp error: (wrong-type-argument sequencep 100)
   replace-regexp-in-string("[&<>\"]" #f(compiled-function (c) #<bytecode 0x1119c0c6891a2a03>) 100)
   url-insert-entities-in-string(100)
   dom-print((svg ((width . 100) (height . 100) (version . "1.1") (xmlns . "http://www.w3.org/2000/svg") (xmlns:xlink . "http://www.w3.org/1999/xlink")) (rect ((width . "100%") (height . "100%") (x . 0) (y . 0) (fill . "blue"))) (text ((fill . "yellow") (stroke . "yellow") (y . 55) (x . 0)) "A text")) t t)
   (let ((svg (svg-create 100 100))) (svg-rectangle svg 0 0 "100%" "100%" :fill "blue") (svg-text svg "A text" :x 0 :y 55 :stroke "yellow" :fill "yellow") (dom-print svg t t))
   (progn (let ((svg (svg-create 100 100))) (svg-rectangle svg 0 0 "100%" "100%" :fill "blue") (svg-text svg "A text" :x 0 :y 55 :stroke "yellow" :fill "yellow") (dom-print svg t t)))
   eval((progn (let ((svg (svg-create 100 100))) (svg-rectangle svg 0 0 "100%" "100%" :fill "blue") (svg-text svg "A text" :x 0 :y 55 :stroke "yellow" :fill "yellow") (dom-print svg t t))) t)
   elisp--eval-last-sexp(t)
   #f(compiled-function () #<bytecode 0x299b97085c5ba>)()
   handler-bind-1(#f(compiled-function () #<bytecode 0x299b97085c5ba>) (error) eval-expression--debug)
   eval-last-sexp(t)
   eval-print-last-sexp(nil)
   funcall-interactively(eval-print-last-sexp nil)
   call-interactively(eval-print-last-sexp nil nil)
   command-execute(eval-print-last-sexp)
  
The cause is that `dom-print' calls the function
`url-insert-entities-in-string' to convert special characters in
attribute value assuming this value is a string, which is not always
true in an SVG DOM.

I propose the attached very simple patch that solves the issue.
Here is a possible changelog:

2025-01-29  David Ponce  <[email-masked]>

	* dom.el (dom-print): Ensure to pass a string to
	`url-insert-entities-in-string'.

With this patch applied the above example prints the expected result:

<svg width="100" height="100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
   <rect width="100%" height="100%" x="0" y="0" fill="blue" />
   <text fill="yellow" stroke="yellow" y="55" x="0">A text</text>
</svg>nil

In GNU Emacs 31.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version
  3.24.43, cairo version 1.18.0) of 2025-01-28
Repository revision: 8c4a4b4eab8ac4dc26e65d552821f3f0b49c79c4
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12014000
System Description: Fedora Linux 40 (KDE Plasma)

Configured using:
  'configure --with-native-compilation=no'

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 M17N_FLT MODULES NOTIFY
INOTIFY PDUMPER PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF
TOOLKIT_SCROLL_BARS TREE_SITTER WEBP X11 XDBE XIM XINPUT2 XPM GTK3 ZLIB

Important settings:
   value of $LC_TIME: fr_FR.utf8
   value of $LANG: fr_FR.UTF-8
   locale-coding-system: utf-8-unix

Major mode: Lisp Interaction

Minor modes in effect:
   tooltip-mode: t
   global-eldoc-mode: t
   eldoc-mode: t
   show-paren-mode: t
   electric-indent-mode: t
   mouse-wheel-mode: t
   tool-bar-mode: t
   menu-bar-mode: t
   file-name-shadow-mode: t
   global-font-lock-mode: t
   font-lock-mode: t
   blink-cursor-mode: t
   minibuffer-regexp-mode: t
   line-number-mode: t
   indent-tabs-mode: t
   transient-mark-mode: t
   auto-composition-mode: t
   auto-encryption-mode: t
   auto-compression-mode: t

Load-path shadows:
None found.

diff --git a/lisp/dom.el b/lisp/dom.el
index fc032058e9f..9eb7c58c38a 100644
--- a/lisp/dom.el
+++ b/lisp/dom.el
@@ -280,7 +280,8 @@ dom-print
 			 (not xml))
 		    (format " %s" (car elem))
 		  (format " %s=\"%s\"" (car elem)
-	                  (url-insert-entities-in-string (cdr elem)))))))
+	                  (url-insert-entities-in-string
+                           (format "%s" (cdr elem))))))))
     (let* ((children (dom-children dom))
 	   (non-text nil))
       (if (null children)