all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Joe Wells <jbw@macs.hw.ac.uk>
To: bug-gnu-emacs@gnu.org
Subject: valid forms of face property: documentation bug, font-lock-{prepend, append}-text-property bug
Date: Mon, 29 Oct 2007 02:19:50 +0000	[thread overview]
Message-ID: <861wbezmpl.fsf@macs.hw.ac.uk> (raw)

BUG #1:  The documentation in (info "(elisp)Special Properties") is
misleading about the legal values of the face property.  The
documentation says this:

  `face'
     You can use the property `face' to control the font and color of
     text.  *Note Faces::, for more information.

     In the simplest case, the value is a face name.  It can also be a
     list; then each element can be any of these possibilities;

        * A face name (a symbol or string).

        * A property list of face attributes.  This has the form
          (KEYWORD VALUE ...), where each KEYWORD is a face attribute
          name and VALUE is a meaningful value for that attribute.
          With this feature, you do not need to create a face each time
          you want to specify a particular attribute for certain text.
          *Note Face Attributes::.

        * A cons cell with the form `(foreground-color . COLOR-NAME)' or
          `(background-color . COLOR-NAME)'.  These elements specify
          just the foreground color or just the background color.
          *Note Color Names::, for the supported forms of COLOR-NAME.

          A cons cell of `(foreground-color . COLOR-NAME)' is
          equivalent to specifying `(:foreground COLOR-NAME)'; likewise
          for the background.

This documentation is misleading.  It implies that

(1) if the property value is not a list, then it must be a face name
    (a symbol), and
(2) if one wants to use the property list (KEYWORD VALUE ...) form,
    then one must wrap it inside an extra list.

In fact, this impression is wrong.  All of these have the same visual
effect when inserted in a buffer with font-lock off:

  #("x" 0 1 (face (:background "green")))
  #("x" 0 1 (face ((:background "green"))))
  #("x" 0 1 (face (background-color . "green")))
  #("x" 0 1 (face ((background-color . "green"))))

But it gets worse!  In fact, the following forms are equivalent:

  #("x" 0 1 (face (highlight bold (:foreground "red"))))
  #("x" 0 1 (face (highlight bold :foreground "red")))
  #("x" 0 1 (face (highlight bold foreground-color . "red")))

Similarly, these two forms are equivalent:

  #("x" 0 1 (face (highlight bold)))
  #("x" 0 1 (face (highlight . bold)))

In contrast, these two forms are not equivalent

  #("x" 0 1 (face ((:foreground "red") highlight bold)))
  #("x" 0 1 (face (:foreground "red" highlight bold)))

Based on my investigations, I think the documentation should say
something like this:

     The value of the face property should be of the form FACE-VALUE,
     where FACE-VALUE is either of the form PRIMITIVE-FACE-VALUE or
     (PRIMITIVE-FACE-VALUE . FACE-VALUE).  PRIMITIVE-FACE-VALUE is
     one of these forms:

        * nil.

        * A face name (a symbol or string).

        * A property list of face attributes.  ...

        * A cons cell with the form `(foreground-color . COLOR-NAME)' or
          `(background-color . COLOR-NAME)'.  ...

But please don't just use my proposal without verifying it against the
actual code which interprets the face property!

BUG #2:  The font-lock-prepend-text-property and
font-lock-append-text-property seem to be designed specifically for
use with the face property (despite their documentation not mentioning
this aim).  They seem to have been written under the assumption that
the documentation in the manual for the face property was correct,
because they can produce useless results in the presence of the
(KEYWORD VALUE ...) form of the face property.  Furthermore, they can
crash in the presence of the (foreground-color . COLOR) form of the
face property.

For example, evaluating

  (let ((s (propertize "#" 'face '(:foreground "red"))))
    (font-lock-prepend-text-property 0 (length s) 'face 'highlight s)
    (insert s))

produces sensible visual results (with red foreground and
darkseagreen2 background), but evaluating

  (let ((s (propertize "#" 'face 'highlight)))
    (font-lock-prepend-text-property 0 (length s) 'face '(:foreground "red") s)
    (insert s)))

fails to use the specified face “highlight”.

Even worse, evaluating this expression raises an error:

  (let ((s (propertize "#" 'face '(foreground-color . "red"))))
    (font-lock-append-text-property 0 (length s) 'face 'highlight s)
    (insert s))

If font-lock is the only user of these two functions, this issue may
not matter, but it makes it difficult to safely use these functions in
other parts of Emacs.  And this means there is no easy way to safely
add a face to a piece of text that already has one or more face
properties.  Someone who wants to do this would have to write their
own versions of font-lock-{prepend,append}-text-property that do the
right thing for all valid values of the face property.

I hope this bug report is useful.

Joe

======================================================================
In GNU Emacs 22.1.1 (i686-pc-linux-gnu, GTK+ Version 2.8.20)
 of 2007-06-27 on artemis
Windowing system distributor `The X.Org Foundation', version 11.0.70000000
configured using `configure  '--prefix=/home/jbw/local2' '--enable-debug' '--disable-nls' '--with-x-toolkit=gtk' 'CFLAGS=-O0 -g3 -ggdb''

Important settings:
  value of $LC_ALL: nil
  value of $LC_COLLATE: nil
  value of $LC_CTYPE: en_US.UTF-8
  value of $LC_MESSAGES: nil
  value of $LC_MONETARY: nil
  value of $LC_NUMERIC: nil
  value of $LC_TIME: jbw
  value of $LANG: nil
  locale-coding-system: utf-8
  default-enable-multibyte-characters: t

Minor modes in effect:
  shell-dirtrack-mode: t
  TeX-source-specials-mode: t
  outline-minor-mode: t
  desktop-save-mode: t
  url-handler-mode: t
  tooltip-mode: t
  mouse-wheel-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  unify-8859-on-encoding-mode: t
  utf-translate-cjk-mode: t
  auto-compression-mode: t
  temp-buffer-resize-mode: t
  size-indication-mode: t
  line-number-mode: t
  transient-mark-mode: t




             reply	other threads:[~2007-10-29  2:19 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-29  2:19 Joe Wells [this message]
     [not found] ` <E1J8NOm-0006N7-3M@fencepost.gnu.org>
2007-12-29  6:52   ` valid forms of face property: documentation bug, font-lock-{prepend, append}-text-property bug Joe Wells
2007-12-30  1:36     ` Richard Stallman
2007-12-30  1:36     ` Richard Stallman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=861wbezmpl.fsf@macs.hw.ac.uk \
    --to=jbw@macs.hw.ac.uk \
    --cc=bug-gnu-emacs@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.