emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Elisp manual on `face' property not clear


From: Drew Adams
Subject: Elisp manual on `face' property not clear
Date: Sat, 24 Jun 2006 16:54:55 -0700

The Elisp manual info on the `face' property is not clear to me. I've read
the various Info nodes a few times, but they don't seem to tell me how text
is displayed when the `face' property (e.g. char property, overlay property,
text property) is a list.

According to my reading of the Info node Special Properties, a `face'
property (e.g. for an overlay) might look something like this:

(my-face1
 (:foreground "Blue" :background "White")
 (foreground . "Red")
 my-face2
 (background . "LightBlue")
 my-face3)

This is not a list of faces, but there are three faces in this list:
my-face*.

Such a list might have multiple entries with the same attribute, say,
(:foreground "Green") (:foreground "Orange"). How are those combined? Which
wins?

I don't see it explained anywhere how the attributes are combined to produce
the visual effect. Which :foreground (or foreground-color) rules? Which
named face rules if several are defined using the same attribute (with
different values)? Are the attributes taken in list order, with the first
one winning when the same attribute is present more than once? How does
inheritance play into this, if one or more of my-face* inherits from other
faces? What if the `face' property list itself has :inherit in one of its
attribute lists?

The info node Displaying Faces doesn't seem to help here. First, it seems
incomplete - the rules of priority given don't seem sufficient. The only
priority they mention is that *between different* types: special glyph, then
region, then overlays (in overlay priority order), then text properties.
They don't say what happens to a merge when there are multiple things of the
same type and priority - for example, multiple overlays of the same priority
or multiple text properties.

Second, this Info node purports to be about faces, not face attributes, but
that doesn't seem correct. The `face' property value above is not a face,
and a `face' property whose value is a list might not include any real faces
(per facep) in it. If Displaying Faces is not necessarily about faces (e.g.
a `face' text or overlay property value need not be a face or even a list of
faces), then the wording should be changed (and perhaps the node should be
moved?). Real faces (per facep) seem like only a corner case here, in fact.

Here's an example, to make the problem concrete: I want to write a simple
function to return the effective foreground color for a character that has a
`face' property: (get-char-property (point) 'face). The result should be a
string that is a color name or # followed by hex RGB components. If no
foreground attribute is found in the `face' property, then the result is
nil. Assume that the `face' property value is legitimate, as defined in the
doc.

I'm at a loss wrt how to do that, because I don't know how :foreground,
foreground-color, and named faces with foregrounds that might all be
contained in the same `face' property value (list) are combined. Faced (no
pun) with multiple foreground candidates in the `face' property value (not
to mention foreground values inherited here and there in the `face' value),
which do I pluck out as the displayed foreground color?

1. Can someone help me understand this?
2. Can the doc be improved to make this clear?

In a first approximation, I can ignore issues like inheritance and frames -
I'm confused enough at this level ;-). I tried looking for some code that
might help. I tried seeing if `face-attribute' or
`face-attribute-merged-with' might at some level work with a list of faces
and face-attribute lists, such as that above, but no such luck. Nearly
everything in faces.el deals only with real faces (per facep). The only
exception I found was `read-face-name', which looks briefly at `face'
property values but quickly jettisons anything that is not a real face.

Thanks in advance for any help you can offer.

----

BTW, speaking of clarity - Do you think this run-on sentence from the doc
string of `get-char-property-and-overlay' could be usefully subdivided?

 Return a cons whose car is the return value of `get-char-property'
 with the same arguments, that is, the value of POSITION's property
 PROP in OBJECT, and whose cdr is the overlay in which the property was
 found, or nil, if it was found as a text property or not found at all.

or moon if green is empty and just-spring is not below prompt, unless....

What is the scope of "or nil"? Is the cdr nil or the entire return value
nil? What is "it" in "if it was found..."?

Who thinks up such sentences? ;-) Please remember: keep it simple - short
sentences; draw a picture (PROPVAL . OVERLAY); use bite-size chunks; and so
on.

Illustrations (simple examples) of possible (esp. typical) values can help
also. Face attributes is one place where we could make things clearer with
simple examples. Another is (!) menus.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]