123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;; CSS abbrev:
- (emmet-defparameter
- emmet-css-unit-aliases
- (gethash "unitAliases" (gethash "css" emmet-preferences)))
- (defun emmet-css-arg-number (input)
- (emmet-parse
- " *\\(\\(?:-\\|\\)[0-9.]+\\)\\(-\\|[A-Za-z]*\\)" 3 "css number arguments"
- (cons (list (elt it 1)
- (let ((unit (elt it 2)))
- (if (= (length unit) 0)
- (if (find ?. (elt it 1)) "em" "px")
- (gethash unit emmet-css-unit-aliases unit))))
- input)))
- (emmet-defparameter
- emmet-css-color-shorten-if-possible
- (gethash "shortenIfPossible" (gethash "color" (gethash "css" emmet-preferences))))
- (emmet-defparameter
- emmet-css-color-case
- (gethash "case" (gethash "color" (gethash "css" emmet-preferences))))
- (emmet-defparameter
- emmet-css-color-trailing-aliases
- (gethash "trailingAliases" (gethash "color" (gethash "css" emmet-preferences))))
- (defun emmet-css-arg-color (input)
- (emmet-parse
- (concat " *#\\([0-9a-fA-F]\\{1,6\\}\\)\\(rgb\\|\\)\\(["
- (emmet-join-string
- (emmet-get-keys-of-hash emmet-css-color-trailing-aliases) "")
- "]\\|\\)")
- 4 "css color argument"
- (let ((color
- (let* ((n (elt it 1))
- (l (length n)))
- (substring
- (cond ((= l 1) (concat (make-list 6 (string-to-char n))))
- ((= l 2) (concat n n n))
- ((= l 3) (concat
- (loop for c in (string-to-list n)
- append (list c c))))
- (t (concat n n)))
- 0 6))))
- (cons
- (let ((rgb-mode (string= (elt it 2) "rgb")))
- (if rgb-mode
- (format "rgb(%d,%d,%d)"
- (string-to-number (substring color 0 2) 16)
- (string-to-number (substring color 2 4) 16)
- (string-to-number (substring color 4 6) 16))
- (concat
- "#"
- (let ((filter (cond ((string= emmet-css-color-case "auto") #'identity)
- ((string= emmet-css-color-case "up") #'upcase)
- (t #'downcase))))
- (funcall
- filter
- (if (and emmet-css-color-shorten-if-possible
- (eql (aref color 0) (aref color 1))
- (eql (aref color 2) (aref color 3))
- (eql (aref color 4) (aref color 5)))
- (concat (mapcar #'(lambda (i) (aref color i)) '(0 2 4)))
- color))))))
- (if (< 0 (length (elt it 3)))
- (cons (gethash (elt it 3) emmet-css-color-trailing-aliases) input)
- input)))))
- (defun emmet-css-arg-something (input)
- (emmet-parse
- " *\\([^ ]+\\)" 2 "css argument"
- (cons (elt it 1) input)))
- (defun emmet-css-parse-arg (input)
- (emmet-run emmet-css-arg-number it
- (emmet-run emmet-css-arg-color it
- (emmet-run emmet-css-arg-something it
- (if (equal input "")
- it
- (cons input ""))))))
- (defun emmet-css-important-p (input)
- (let ((len (length input)))
- (and (< 0 len)
- (char-equal (aref input (1- len)) ?!))))
- (defun emmet-css-parse-args (args)
- (when args
- (let ((rt nil))
- (loop
- (emmet-pif
- (emmet-css-parse-arg args)
- (loop for i on it do (push (car i) rt)
- while (consp (cdr i))
- finally (setq args (cdr i)))
- (return (nreverse rt)))))))
- (defun emmet-css-split-args (exp)
- (emmet-aif
- (string-match "\\(?:[ #0-9$]\\|-[0-9]\\)" exp)
- (list (substring exp 0 it) (substring exp it))
- (list exp nil)))
- (defun emmet-css-split-vendor-prefixes (input)
- (emmet-parse
- "\\(-[wmso]+-\\|-\\|\\)\\(.*\\)" 3 "css vendor prefixes"
- (list (elt it 2)
- (let ((vp (elt it 1)))
- (if (not (string= vp ""))
- (if (string= vp "-") 'auto
- (string-to-list (subseq vp 1 -1))))))))
- (defun emmet-css-subexpr (exp)
- (let* ((importantp (emmet-css-important-p exp)))
- (destructuring-bind (exp vp)
- (emmet-css-split-vendor-prefixes exp)
- (destructuring-bind (key args)
- (emmet-css-split-args (if importantp (subseq exp 0 -1) exp))
- `(,key ,vp
- ,importantp
- ,@(emmet-css-parse-args args))))))
- (defun emmet-css-toknize (str)
- (let* ((i (split-string str "+"))
- (rt nil))
- (loop
- (let ((f (first i))
- (s (second i)))
- (if f
- (if (and s (or (string= s "")
- (string-match "^\\(?:[ #0-9$]\\|-[0-9]\\)" s)))
- (progn
- (setf rt (cons (concat f "+" s) rt))
- (setf i (cddr i)))
- (progn
- (setf rt (cons f rt))
- (setf i (cdr i))))
- (return (nreverse rt)))))))
- (defun emmet-css-expr (input)
- (mapcar #'emmet-css-subexpr
- (emmet-css-toknize input)))
- (emmet-defparameter
- emmet-css-snippets
- (gethash "snippets" (gethash "css" emmet-snippets)))
- (emmet-defparameter
- emmet-sass-snippets
- (gethash "snippets" (gethash "sass" emmet-snippets)))
- (emmet-defparameter
- emmet-css-unitless-properties
- (gethash "unitlessProperties" (gethash "css" emmet-preferences)))
- (emmet-defparameter
- emmet-css-unitless-properties-regex
- (concat "^\\(:?" (emmet-join-string
- emmet-css-unitless-properties "\\|")
- "\\):.*$"))
- (defun emmet-css-instantiate-lambda (str)
- (cl-flet ((insert-space-between-name-and-body
- (str)
- (if (string-match "^\\([a-z-]+:\\)\\(.+\\)$" str)
- (emmet-join-string
- (mapcar (lambda (ref) (match-string ref str)) '(1 2)) " ")
- str))
- (split-string-to-body
- (str args-sym)
- (let ((rt '(concat)) (idx-max 0))
- (loop for i from 0 to 255 do
- (emmet-aif
- (string-match "\\(?:|\\|${\\(?:\\([0-9]\\)\\|\\)\\(?::\\(.+?\\)\\|\\)}\\)" str)
- (destructuring-bind (mat idx def)
- (mapcar (lambda (ref) (match-string ref str)) '(0 1 2))
- (setf rt
- `((or
- (nth ,(let ((cur-idx (if idx (1- (string-to-number idx)) i)))
- (setf idx-max (max cur-idx idx-max)))
- ,args-sym)
- ,(or def ""))
- ,(substring str 0 it) ;; ordered to reverse
- ,@rt))
- (setf str (substring str (+ it (length mat)))))
- ;; don't use nreverse. cause bug in emacs-lisp.
- (return (cons idx-max (reverse (cons str rt)))))))))
- (let ((args (gensym))
- (str (insert-space-between-name-and-body str)))
- (destructuring-bind (idx-max . body) (split-string-to-body str args)
- (eval
- `(lambda (&rest ,args)
- (progn
- (when (nthcdr ,idx-max ,args)
- (setf (nthcdr ,idx-max ,args)
- (list (emmet-join-string
- (nthcdr ,idx-max ,args) " "))))
- ,body)))))))
- (emmet-defparameter
- emmet-vendor-prefixes-properties
- (gethash "vendorPrefixesProperties" (gethash "css" emmet-preferences)))
- (emmet-defparameter
- emmet-vendor-prefixes-default
- (list "webkit" "moz" "ms" "o"))
- (defun emmet-css-transform-vendor-prefixes (line vp)
- (let ((key (subseq line 0 (or (position ?: line) (length line)))))
- (let ((vps (if (eql vp 'auto)
- (gethash key
- emmet-vendor-prefixes-properties
- emmet-vendor-prefixes-default)
- (mapcar (lambda (v)
- (cond ((= v ?w) "webkit")
- ((= v ?m) "moz")
- ((= v ?s) "ms")
- ((= v ?o) "o")))
- vp))))
- (emmet-join-string
- (append (mapcar (lambda (v) (concat "-" v "-" line)) vps)
- (list line))
- "\n"))))
- (defun emmet-css-transform-exprs (exprs)
- (emmet-join-string
- (mapcar
- #'(lambda (expr)
- (let*
- ((hash-map (if emmet-use-sass-syntax emmet-sass-snippets emmet-css-snippets))
- (basement
- (emmet-aif
- (or (gethash (car expr) hash-map) (gethash (car expr) emmet-css-snippets))
- (let ((set it) (fn nil) (unitlessp nil))
- (if (stringp set)
- (progn
- ;; new pattern
- ;; creating print function
- (setf fn (emmet-css-instantiate-lambda set))
- ;; get unitless or no
- (setf unitlessp
- (not (null (string-match
- emmet-css-unitless-properties-regex set))))
- ;; caching
- (puthash (car expr) (cons fn unitlessp) hash-map))
- (progn
- ;; cache hit.
- (setf fn (car set))
- (setf unitlessp (cdr set))))
- (apply fn
- (mapcar
- #'(lambda (arg)
- (if (listp arg)
- (if unitlessp (car arg)
- (apply #'concat arg))
- arg))
- (cdddr expr))))
- (concat (car expr) ": "
- (emmet-join-string
- (mapcar #'(lambda (arg)
- (if (listp arg) (apply #'concat arg) arg))
- (cdddr expr)) " ")
- ";"))))
- (let ((line
- (if (caddr expr)
- (concat (subseq basement 0 -1) " !important;")
- basement)))
- ;; remove trailing semicolon while editing Sass files
- (if (and emmet-use-sass-syntax (equal ";" (subseq line -1)))
- (setq line (subseq line 0 -1)))
- (emmet-aif
- (cadr expr)
- (emmet-css-transform-vendor-prefixes line it)
- line))))
- exprs)
- "\n"))
- (defun emmet-css-transform (input)
- (emmet-css-transform-exprs (emmet-css-expr input)))
|