(require 'url)
(require 'htmlize) (require 'scpaste)
(defun scpaste-stylize-list-faces ()
(let ((print-length nil))
(insert (concat "(defvar scpaste-stylize-faces\n'("
(mapconcat 'symbol-name (face-list) "\n")
"))") )))
(defun htmlize-face-size (face)
(let* ((face-list (list face))
(head face-list)
(tail face-list))
(while head
(let ((inherit (face-attribute (car head) :inherit)))
(cond ((listp inherit)
(setcdr tail (cl-copy-list inherit))
(setq tail (last tail)))
((eq inherit 'unspecified))
((consp inherit) (setcdr tail (list (car inherit)))
(setq tail (cdr tail))
)
(t
(setcdr tail (list inherit))
(setq tail (cdr tail))
))
)
(setq head (cl-remove-if
(lambda (x) (equal (symbol-name x) "quote"))
head))
(pop head))
(setq face-list (cl-remove-if
(lambda (x) (equal (symbol-name x) "quote"))
face-list))
(let ((size-list
(cl-loop
for f in face-list
for h = (and (facep f) (face-attribute f :height))
collect (if (eq h 'unspecified) nil h))))
(cl-reduce 'htmlize-merge-size (cons nil size-list)))))
(defvar scpaste-stylize-faces
'(default
font-lock-comment-face
font-lock-comment-delimiter-face
font-lock-string-face
font-lock-doc-face
font-lock-doc-markup-face
font-lock-keyword-face
font-lock-builtin-face
font-lock-function-name-face
font-lock-variable-name-face
font-lock-type-face
font-lock-constant-face
font-lock-warning-face
font-lock-negation-char-face
font-lock-preprocessor-face
font-lock-regexp-grouping-backslash
font-lock-regexp-grouping-construct))
(defun scpaste-stylize-css ()
"Create a style.css and paste it in your remote directory."
(interactive)
(let* ((faces scpaste-stylize-faces)
(face-map (htmlize-make-face-map faces))
(buffer-faces faces)
(tmp-file (concat temporary-file-directory "style.css"))
(full-url (concat scpaste-http-destination
"/style.css")))
(with-temp-buffer
(htmlize-css-insert-head buffer-faces face-map)
(goto-char (point-min))
(delete-region (point-min) (re-search-forward "<!--\n"))
(goto-char (point-max))
(re-search-backward "-->")
(delete-region (point) (point-max))
(css-mode)
(indent-region (point-min) (point-max))
(write-file tmp-file))
(let* ((identity (if scpaste-scp-pubkey
(concat "-i " scpaste-scp-pubkey) ""))
(port (if scpaste-scp-port (concat "-P " scpaste-scp-port)))
(invocation (concat scpaste-scp " -q " identity " " port))
(command (concat invocation " " tmp-file " "
scpaste-scp-destination "/"))
(error-buffer "*scp-error*")
(retval (shell-command command nil error-buffer))
(select-enable-primary t))
(delete-file tmp-file)
(if (= retval 0)
(progn (kill-new full-url)
(message "Pasted to %s (on kill ring)" full-url))
(pop-to-buffer error-buffer)
(help-mode-setup)))
))
(defun scpaste-stylize (original-name)
"Paste the current buffer via `scp' to `scpaste-http-destination'.
If ORIGINAL-NAME is an empty string, then the buffer name is used
for the file name."
(interactive (list (scpaste-read-name)))
(let* ((b (generate-new-buffer (generate-new-buffer-name "scpaste")))
(pre-hl-line (and (featurep 'hl-line) hl-line-mode
(progn (hl-line-mode -1) t)))
(hb (funcall scpaste-html-converter))
(name (replace-regexp-in-string "[/\\%*:|\"<> ]+" "_"
original-name))
(full-url (concat scpaste-http-destination
"/" (url-hexify-string name) ".html"))
(tmp-file (concat temporary-file-directory name))
(tmp-hfile (concat temporary-file-directory name ".html")))
(when pre-hl-line
(hl-line-mode 1))
(save-excursion
(copy-to-buffer b (point-min) (point-max))
(switch-to-buffer b)
(write-file tmp-file)
(kill-buffer b)
(switch-to-buffer hb)
(goto-char (point-min))
(search-forward "</body>\n</html>")
(insert (format (scpaste-footer)
(current-time-string)
(substring full-url 0 -5)))
(goto-char (point-min))
(let* ((start-string "<style type=\"text/css\">\n *<!--")
(end-string "\n *-->\n *</style>")
(end (re-search-forward end-string))
(start (re-search-backward start-string))
)
(delete-region start end)
(goto-char (point-min))
(re-search-forward "</title>")
(insert "\n<link rel=\"stylesheet\" href=\"style.css\">")
)
(write-file tmp-hfile)
(kill-buffer hb))
(let* ((identity (if scpaste-scp-pubkey
(concat "-i " scpaste-scp-pubkey) ""))
(port (if scpaste-scp-port (concat "-P " scpaste-scp-port)))
(invocation (concat scpaste-scp " -q " identity " " port))
(command (concat invocation " " tmp-file " " tmp-hfile " "
scpaste-scp-destination "/"))
(error-buffer "*scp-error*")
(retval (shell-command command nil error-buffer))
(select-enable-primary t))
(delete-file tmp-file)
(delete-file tmp-hfile)
(if (= retval 0)
(progn (kill-new full-url)
(message "Pasted to %s (on kill ring)" full-url))
(pop-to-buffer error-buffer)
(help-mode-setup)))))
(defun scpaste-stylize-region (name)
"Paste the current region via `scpaste'.
NAME is used for the file name."
(interactive (list (scpaste-read-name (format "-%s-%s" (region-beginning)
(region-end)))))
(let ((region-contents (buffer-substring (mark) (point))))
(with-temp-buffer
(insert region-contents)
(scpaste-stylize name))))
(defun scpaste-stylize-index ()
"Generate an index of all existing pastes on server on the splash page."
(interactive)
(let* ((dest-parts (split-string scpaste-scp-destination ":"))
(files (shell-command-to-string (concat scpaste-ssh " "
(car dest-parts) " ls "
(cadr dest-parts))))
(file-list (split-string files "\n")))
(save-excursion
(with-temp-buffer
(insert-file-contents scpaste-el-location)
(goto-char (point-min))
(search-forward ";;; Commentary")
(forward-line -1)
(insert "\n;;; Pasted Files\n\n")
(dolist (file file-list)
(when (and (string-match "\\.html$" file)
(not (string-match "private" file)))
(insert (concat ";; * <" scpaste-http-destination "/" file ">\n"))))
(emacs-lisp-mode)
(if (fboundp 'font-lock-ensure)
(progn (font-lock-mode nil)
(font-lock-ensure)
(jit-lock-mode t))
(with-no-warnings (font-lock-fontify-buffer)))
(rename-buffer "SCPaste")
(write-file (concat temporary-file-directory "scpaste-index"))
(scpaste-stylize "index")))))
(provide 'scpaste-stylize)