konr
konr

Reputation: 2565

How to nest various `propertize`s?

I want to do the elisp equivalent of

 <font color="red">normal<b>bold</b></font>

I've tried

 (propertize (concat "normal" 
               (propertize "bold" 'font-lock-face 
                                  '(:weight bold))) 
  'font-lock-face '(:foreground "red"))

Yet the 'red' property overwrites the 'bold' property and I end up with

#("normalbold" 0 6
  (font-lock-face
   (:foreground "red"))
  6 10
  (font-lock-face
   (:foreground "red")))

Is it doable?

Thanks!

Upvotes: 4

Views: 1423

Answers (1)

James Porter
James Porter

Reputation: 1923

I don't think nesting can be done with the functions elisp provides. The docs suggest propertizing each part of the string individually and then concatenating them:

" To put different properties on various parts of a string, you can construct each part with propertize and then combine them with concat:

      (concat
       (propertize "foo" 'face 'italic
                   'mouse-face 'bold-italic)
       " and "
       (propertize "bar" 'face 'italic
                   'mouse-face 'bold-italic))
           ⇒ #("foo and bar"
                       0 3 (face italic mouse-face bold-italic)
                       3 8 nil
                       8 11 (face italic mouse-face bold-italic))

"

Which in your case would look something like:

(concat (propertize "normal" 'font-lock-face '(:foreground "red" ))
        (propertize "bold" 'font-lock-face '(:foreground "red" :weight bold)))

Without knowing more about your use case I can't be sure this will work for you. If it won't, you could try using add-text-properties (also described in the docs), which you can use to statefully modify the text properties of a string.

Upvotes: 2

Related Questions