From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.io/gmane.emacs.gnus.general/47153 Path: main.gmane.org!not-for-mail From: Paul Moore Newsgroups: gmane.emacs.gnus.general Subject: User format functions - text properies get lost (XEmacs) Date: Sat, 12 Oct 2002 16:39:53 +0100 Sender: owner-ding@hpc.uh.edu Message-ID: NNTP-Posting-Host: localhost.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: main.gmane.org 1034437358 22210 127.0.0.1 (12 Oct 2002 15:42:38 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Sat, 12 Oct 2002 15:42:38 +0000 (UTC) Return-path: Original-Received: from malifon.math.uh.edu ([129.7.128.13]) by main.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 180OPS-0005le-00 for ; Sat, 12 Oct 2002 17:42:34 +0200 Original-Received: from sina.hpc.uh.edu ([129.7.128.10] ident=lists) by malifon.math.uh.edu with esmtp (Exim 3.20 #1) id 180OLy-0003CK-00; Sat, 12 Oct 2002 10:38:58 -0500 Original-Received: by sina.hpc.uh.edu (TLB v0.09a (1.20 tibbs 1996/10/09 22:03:07)); Sat, 12 Oct 2002 10:39:41 -0500 (CDT) Original-Received: from sclp3.sclp.com (qmailr@sclp3.sclp.com [209.196.61.66]) by sina.hpc.uh.edu (8.9.3/8.9.3) with SMTP id KAA24970 for ; Sat, 12 Oct 2002 10:39:28 -0500 (CDT) Original-Received: (qmail 3634 invoked by alias); 12 Oct 2002 15:40:21 -0000 Original-Received: (qmail 3629 invoked from network); 12 Oct 2002 15:40:21 -0000 Original-Received: from anchor-post-32.mail.demon.net (194.217.242.90) by gnus.org with SMTP; 12 Oct 2002 15:40:21 -0000 Original-Received: from morpheus.demon.co.uk ([158.152.8.30]) by anchor-post-32.mail.demon.net with smtp (Exim 3.35 #1) id 180OLd-0003Dh-0W for ding@gnus.org; Sat, 12 Oct 2002 16:38:38 +0100 Original-Received: from morpheus.demon.co.uk (HELO MORPHEUS) [127.0.0.1] by morpheus.demon.co.uk (127.0.0.1) with ESMTP (Classic Hamster Vr. 1.3 Build 1.3.23.191) ; Sat, 12 Oct 2002 16:39:54 +0100 Original-To: ding@gnus.org Original-Lines: 72 User-Agent: Gnus/5.090007 (Oort Gnus v0.07) XEmacs/21.5 (brussels sprouts, i586-pc-win32) X-Posting-Agent: Hamster/1.3.23.191 Precedence: list X-Majordomo: 1.94.jlt7 Xref: main.gmane.org gmane.emacs.gnus.general:47153 X-Report-Spam: http://spam.gmane.org/gmane.emacs.gnus.general:47153 --=-=-= With a lot of help from Jesper Harder, I have identified a problem in Oort Gnus running under XEmacs. The problem arises when a user format function returns a string with text properties set. My original example was a "gnus-user-format-function-f" which returned the sender's name (basically like %f) but the name is in red if the sender is in my BBDB. I set the properties '(gnus-face t face red), but found that the summary buffer did not show the colour. On investigation, it became clear that the problem was that gnus-parse-simple-format produces a form which uses FORMAT to generate the summary line. On FSF Emacs, format preserves text properties, but in XEmacs, it does not, returning a string with no properties set. The attached patch fixes this problem. It's a little rough around the edges, mainly because I have pretty much no experience in elisp programming, but it does fix the problem for me. Is it possible for this workaround to be included, in some form, in Gnus proper? I don't see any way of fixing the problem in user code (ie, *without* patching Gnus). Some things which need to be addressed (and which are basically beyond me...) 1. The code I added to gnus-parse-simple-format only uses gnus-simple-format for XEmacs. This is to avoid FSF Emacs users having to take a performance hit from using a Lisp function where their built-in format function is fine. Jesper suggested using (eval-and-compile (unless (featurep 'xemacs) (defalias 'gnus-simple-format 'format))) instead, but (a) I couldn't decide where to put it, and (b) I suspect my solution is simpler. But I'm not sure, and I have no FSF Emacs to test it on, so I'd appreciate comments. 2. The code only handles %s and %%. Under XEmacs these are the only two format codes which are generated. However, if gnus-use-correct-string-widths is false in XEmacs, %Ns codes are generated (for numeric N). Adding code to gnus-simple-format to cope with this case is possible, but it complicates (and slows down) the code. Is it worth it? Alternatively, is there another way of achieving the same effect - maybe make Gnus never generate the %Ns codes for XEmacs (the gnus-use-correct-string-widths code %manages it by trimming the strings before passing them to format, %I think - is something similar possible?) 3. The whole thing (using a format replacement coded in lisp) is going to give a performance hit. I'm sure my code isn't anywhere near optimal - can anyone help in making it faster? 4. Even if optimised, the whole thing is still going to be slower than using format directly. And as it only causes problems in a few obscure cases, would it be worth making the whole thing optional, via a user configuration option? I've not the slightest idea how to do something like that, so I'm afraid I can't offer code here, just the suggestion (and the suggestion was originally Jesper's in any case :-)) I'd appreciate any comments - this is my first attempt at submitting a patch for Gnus, so I apologise if I've made any obvious blunders, in coding or in procedure. Thanks in particular to Jesper, who helped me follow this through until I understood precisely where the problem lay. Paul. --=-=-= Content-Disposition: attachment; filename=GnusPatch.txt Content-Description: Gnus patch --- gnus-spec.el.orig Wed Feb 20 00:15:32 2002 +++ gnus-spec.el Sat Oct 12 16:38:48 2002 @@ -396,6 +396,24 @@ ,(when (not side) '(make-string need ?\ ))) val))))) +(defun gnus-simple-format (str &rest objects) + ;; A replacement for FORMAT which only handles %s and %% formats. + ;; Xemacs FORMAT does not preserve text properties on the input + ;; strings, whereas this version does. Without this function, returning + ;; strings with properties set from user-defined spec functions does not + ;; work in xemacs. Arguably, this function should just be an alias for + ;; format in FSF emacs (where properties are preserved), for speed if + ;; nothing else. + (with-temp-buffer + (insert str) + (goto-char (point-min)) + (while (search-forward "%s" nil t) + (let ((obj (car objects))) + (replace-match (if (stringp obj) obj (format "%s" obj)) + nil t)) + (setq objects (cdr objects))) + (gnus-replace-in-string (buffer-string) "%%" "%"))) + (defun gnus-parse-format (format spec-alist &optional insert) ;; This function parses the FORMAT string with the help of the ;; SPEC-ALIST and returns a list that can be eval'ed to return the @@ -642,6 +660,19 @@ ;; A single string spec in the end of the spec. ((string-match "\\`\\([^%]+\\)%[sc]\\'" fstring) (list (match-string 1 fstring) (car flist))) + ;; Nothing but %% and (bare) %s specs. + ;; We use a special replacement for format here to work around the + ;; fact that XEmacs FORMAT does not preserve text properties, + ;; without having to reimplement FORMAT in all its glory. + ;; The code above never uses format codes other than %% and %s for + ;; XEmacs in any case. (It uses %NNNs if gnus-use-correct-string-widths + ;; is not set, but we don't consider that here - it's a non-standard + ;; case and complicates the implementation of gnus-simple-format). + ;; Only do this for XEmacs, as we don't want FSF Emacs users to suffer + ;; an unnecessary performance hit. + ((and (featurep 'xemacs) + (string-match "\\`\\([^%]\\|%[s%]\\)*\\'" fstring))) + (list (cons 'gnus-simple-format (cons fstring (nreverse flist))))) ;; A more complex spec. (t (list (cons 'format (cons fstring (nreverse flist))))))) --=-=-=--