(setq no-byte-compile t) (require 'cl-lib) (require 'package) (defvar +excluded-package-names+ '(tramp-theme color-theme airline-themes)) (defun fussy-string-ends-with (str suffix) (and (< (length suffix) (length str)) (string= suffix (cl-subseq str (- (length str) (length suffix)))))) (defun fussy-is-theme-p (pkg-entry) (let ((name (symbol-name (cl-first pkg-entry)))) (and (or (fussy-string-ends-with name "-theme") (fussy-string-ends-with name "-themes")) (not (cl-member (cl-first pkg-entry) +excluded-package-names+))))) (defun fussy-themes-packages () "Setting FUSSY-THEME-PACKAGES-TO-LOAD at the command line will restrict the package installation step to just these packages. This function checks that FUSSY-THEME-PACKAGES-TO-LOAD is bound and if it is, returns it, otherwise, it filters all theme packages from the PACKAGE-ARCHIVE-CONTENTS and returns those." (if (boundp 'fussy-theme-packages-to-load) fussy-theme-packages-to-load (cl-remove-if-not 'fussy-is-theme-p package-archive-contents))) (defun fussy-themes-to-exclude-from-image-generation () "Setting FUSSY-EXCLUDED-THEMES from the command line will tell the script not to load those themes. This function simply checks that the variable is bound and returns its value, a list of symbols, returning nil if not." (when (boundp 'fussy-excluded-themes) fussy-excluded-themes)) (defun fussy-screenshot-svg (filename) "Save a screenshot of the current frame as an SVG image to a file called filename." (let* ((tmpfile (make-temp-file "Emacs" nil ".svg")) (data (x-export-frames nil 'svg))) (with-temp-file tmpfile (insert data)) (copy-file tmpfile filename t))) (defun install-all-themes () (let ((failed-to-install nil)) (cl-dolist (theme (fussy-themes-packages)) (let ((package-name (if (symbolp theme) theme (cl-first theme)))) (condition-case nil (package-install package-name) (error (push package-name failed-to-install))))) failed-to-install)) (defun locate-theme-package (theme) "Given a symbol naming a theme, find the name of the package that the theme came from." (let ((theme-file (locate-file (concat (symbol-name theme) "-theme.el") (custom-theme--load-path) '("" "c")))) (string-join (butlast (split-string (cadr (reverse (file-name-split (file-name-directory theme-file)))) "-")) "-"))) (defun fussy-generate-all-theme-images (&rest files) (let ((failed-to-load nil) (failed-to-generate-image nil) (failed-to-install (install-all-themes))) (message "All themes have been loaded") (cl-dolist (theme (custom-available-themes)) (unless (member theme (fussy-themes-to-exclude-from-image-generation)) (message (format "Generating for theme: %s" theme)) (unwind-protect (when (condition-case nil (progn (load-theme theme t) t) (error (push theme failed-to-load) (message "... failed to load!") nil)) (dolist (file files) (let* ((theme-package (locate-theme-package theme)) (svg-file (concat (getenv "HOME") "/" theme-package "/" (symbol-name theme) "/" (file-name-base file) "." (file-name-extension file) ".svg"))) (make-directory (file-name-directory svg-file) t) (condition-case nil (progn (find-file file) (delete-other-windows) (sleep-for 1) (fussy-screenshot-svg svg-file)) (error (push (cons theme file) failed-to-generate-image)))))))) (disable-theme theme)) (with-temp-file (concat (getenv "HOME") "/" "errors.el") (insert (prin1-to-string (list :load-errors failed-to-load :generation-errors failed-to-generate-image :install-errors failed-to-install)))) (message "FINISHED GENERATING THEME IMAGES"))) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) (add-to-list 'default-frame-alist '(font . "DejaVu Sans Mono-10")) (package-initialize) (package-refresh-contents) (package-install 'compat) (require 'compat) (set-frame-height (frame-focus) 50) (set-frame-width (frame-focus) 100) (defun rel-to-home (file) (concat (getenv "HOME") "/" file)) (fussy-generate-all-theme-images (rel-to-home "../fussy.lisp") (rel-to-home "../bandleader.py") (rel-to-home"../conway.cpp")) (kill-emacs)