From 9d76a64745f94870e9783bf78d50938abab56bff Mon Sep 17 00:00:00 2001 From: Tom Willemsen Date: Thu, 17 May 2012 18:41:04 +0200 Subject: [PATCH] Initial commit --- .gitignore | 1 + project-template.el | 77 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 .gitignore create mode 100644 project-template.el diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c531d98 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.elc diff --git a/project-template.el b/project-template.el new file mode 100644 index 0000000..db3bb35 --- /dev/null +++ b/project-template.el @@ -0,0 +1,77 @@ +(defvar pt-templates-directory "~/.emacs.d/templates" + "Where templates are stored.") + +(defvar pt-template-var-regexp "__\\([^_ \t\n]+\\)__" + "Regexp which identifies a variable in a template.") + +(defvar pt-value-alist nil) + +(defun pt-replace-all (from to str) + (while (string-match from str) + (set 'str (replace-match to t t str))) + str) + +(defun pt-get-replacement (key) + (let ((replacement (assoc key pt-value-alist))) + (when (eq replacement nil) + (set 'replacement + `(,key . ,(read-from-minibuffer (concat key ": ")))) + (add-to-list 'pt-value-alist replacement)) + replacement)) + +(defun pt-parse-file-name (filename) + (while (string-match pt-template-var-regexp filename) + (let* ((tpl-var (match-string 1 filename)) + (replacement-value (pt-get-replacement tpl-var))) + (set 'filename (replace-match (cdr replacement-value) t t + filename)))) + + (let ((noext (file-name-sans-extension filename)) + (ext (file-name-extension filename t))) + (set 'noext (pt-replace-all "\\." "/" noext)) + (concat noext ext))) + +(defun pt-parse-file (file) + (insert-file-contents file) + + (while (re-search-forward pt-template-var-regexp nil t) + (let* ((tpl-var (match-string 1)) + (replacement-value (pt-get-replacement tpl-var))) + (replace-match (cdr replacement-value) t t)))) + +(defun pt-parse-and-copy-file (src dst) + (let* ((parsed-dst (pt-parse-file-name dst)) + (parsed-dst-dir (file-name-directory parsed-dst))) + (when (not (file-exists-p parsed-dst-dir)) + (make-directory parsed-dst-dir t)) + + (with-temp-file parsed-dst + (pt-parse-file src)))) + +(defun pt-copy-directory (directory to) + (let ((files (directory-files directory t "[^.]\\{1,2\\}$" t))) + (while files + (let* ((src-filename (car files)) + (dst-filename + (concat to "/" (file-name-nondirectory src-filename)))) + (if (file-directory-p src-filename) + (pt-copy-directory src-filename dst-filename) + (if (string-equal (file-name-extension src-filename) "etpl") + (pt-parse-and-copy-file + src-filename (file-name-sans-extension dst-filename)) + (if (not (file-exists-p to)) + (make-directory to t) + (unless (file-directory-p to) + (error + (concat "Cannot create project at %s, file " + "already exists and is not a directory.") to))) + + (copy-file src-filename dst-filename)))) + (set 'files (cdr files))))) + +;;;###autoload +(defun pt-create-project-from-template (template destination) + (interactive "MTemplate: \nGDestination: ") + (let ((pt-value-alist)) + (pt-copy-directory + (concat pt-templates-directory "/" template) destination)))