简体   繁体   中英

Adding a created color-code to font-lock

I'm trying to syntax-highlight RGB color codes in Emacs. I've got the #hex values working, but though I was bashing my head against this for a few hours yesterday I couldn't get it to work right:

(defvar rgb-color-keywords
  '(("rgb([0-9]+,[0-9]+,[0-9]+)"
     (0 (setq color-channels-rgb (substring (match-string-no-properties 0) 4 -1))
       (setq color-channels (split-string color-channels-rgb ","))
       (setq red-channel (format "%02X" (string-to-number (elt color-channels 0))))
       (setq green-channel (format "%02X" (string-to-number (elt color-channels 1))))
       (setq blue-channel (format "%02X" (string-to-number (elt color-channels 2))))
       (put-text-property
        (match-beginning 0)
        (match-end 0)
        'face (list :background (concat "#" red-channel green-channel blue-channel)))))))

where I later call (font-lock-add-keywords nil rgb-color-keywords) . I know the basics are right since I do something very similar for short and long hex values that works (which are themselves based on code I found lurking on the net), and I've tested the basic regex in the Emacs interpreter, but for whatever reason this is just not working. The individual parts all seem to work fine also.

On the plus side, I learned a bunch of lisp yesterday ....

For what it's worth, though certainly a code fix would be sufficient, my mental model of this handling is fuzzy so I'd love a "why" on what I missed.


@sds just about got it, and pointed me in the right direction. This ended up working:

 (defvar rgb-color-keywords '(("rgb([0-9]+, *[0-9]+, *[0-9]+)" (0 (put-text-property (match-beginning 0) (match-end 0) 'face (list :background (let ((color-channels (split-string (substring (match-string-no-properties 0) 4 -1) ","))) (format "#%02X%02X%02X" (string-to-number (nth 0 color-channels)) (string-to-number (nth 1 color-channels)) (string-to-number (nth 2 color-channels)))))))))) 

You have several forms where only one is permitted. What you want, I think, is this:

(defvar rgb-color-keywords
  '(("rgb([0-9]+ *,[0-9]+ *,[0-9]+ *)"
     (0
      (let ((channels (split-string (substring (match-string-no-properties 0) 4 -1)
                                    "," nil " *")))
        (list 'face (list :background
                          (format "#%02X%02X%02X"
                                  (string-to-number (nth 0 color-channels))
                                  (string-to-number (nth 1 color-channels))
                                  (string-to-number (nth 2 color-channels))))))))))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM