From a281f040cd35dffe171d5b7d6b00fe03163be6a0 Mon Sep 17 00:00:00 2001 From: Tom Willemsen Date: Sun, 17 Feb 2013 23:09:24 +0100 Subject: Move .emacs.d to emacs Since it's no longer placed directly in the home directory it doesn't need to be named exacly the same. --- emacs/site-lisp/eltuki.el | 232 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 emacs/site-lisp/eltuki.el (limited to 'emacs/site-lisp/eltuki.el') diff --git a/emacs/site-lisp/eltuki.el b/emacs/site-lisp/eltuki.el new file mode 100644 index 0000000..224e9ab --- /dev/null +++ b/emacs/site-lisp/eltuki.el @@ -0,0 +1,232 @@ +;;; eltuki.el --- Tekuti functions + +;; Copyright (C) 2012 Tom Willemsen + +;; Author: Tom Willemsen +;; Keywords: convenience + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; Tekuti functions. + +;;; Code: + +(require 'org) + +(defgroup eltuki + nil + "tekuti functions in Emacs." + :group 'external) + +(defcustom eltuki-blog-dir "~/blog" + "Plain blog post directory, not the git repository." + :group 'eltuki + :type 'string) + +(defcustom eltuki-default-status "publish" + "Default status to use when status is unknown." + :group 'eltuki + :type 'string) + +(defcustom eltuki-default-comment-status "open" + "Default status for comments." + :group 'eltuki + :type 'string) + +(define-skeleton eltuki-post + "Create a post template for eltuki." + "" + "#+TITLE: " (skeleton-read "Title: ") "\n" + "#+TIMESTAMP: \n" + "#+TAGS: " (skeleton-read "Tags (comma separated): ") "\n" + "\n" + _) + +(defun eltuki-new-post () + (interactive) + (switch-to-buffer (get-buffer-create "*eltuki*")) + (org-mode) + (eltuki-post)) + +(defun eltuki-get-title () + (save-excursion + (goto-char (point-min)) + (if (re-search-forward "^#\\+TITLE: \\(.*\\)$" nil t) + (buffer-substring-no-properties + (match-beginning 1) (match-end 1)) + (error "Post has no title.")))) + +(defun eltuki-set-title (title) + (interactive "MTitle: ") + (setq title (concat " " title)) + (save-excursion + (goto-char (point-min)) + (if (re-search-forward "^#\\+TITLE:\\(.*\\)$" nil t) + (replace-match title t t nil 1) + (insert "#+TITLE:" title "\n") + (unless (= (char-after) ?\n) + (insert-char ?\n))))) + +(defun eltuki-get-timestamp () + (save-excursion + (goto-char (point-min)) + (if (re-search-forward "^#\\+TIMESTAMP: \\([[:digit:]]+\\)$" nil t) + (match-string 1) + (format-time-string "%s")))) + +(defun eltuki-set-timestamp () + (interactive) + (save-excursion + (goto-char (point-min)) + (let ((newtime (format-time-string " %s"))) + (if (re-search-forward "^#\\+TIMESTAMP:\\(.*\\)$" nil t) + (replace-match newtime nil t nil 1) + (when (search-forward "\n\n" nil t) + (backward-char)) + (insert "#+TIMESTAMP:" newtime "\n"))))) + +(defun eltuki-get-tags () + (save-excursion + (goto-char (point-min)) + (when (re-search-forward "^#\\+TAGS: \\(.*\\)$" nil t) + (buffer-substring-no-properties + (match-beginning 1) (match-end 1))))) + +(defun eltuki-set-tags (tags) + (interactive "MTags: ") + (setq tags (concat " " tags)) + (save-excursion + (goto-char (point-min)) + (if (re-search-forward "^#\\+TAGS:\\(.*\\)$" nil t) + (replace-match tags t t nil 1) + (when (search-forward "\n\n" nil t) + (backward-char)) + (insert "#+TAGS:" tags "\n")))) + +(defun eltuki-get-status () + (save-excursion + (goto-char (point-min)) + (if (re-search-forward "^#\\+STATUS: \\(draft\\|publish\\)$" nil t) + (buffer-substring-no-properties + (match-beginning 1) (match-end 1)) + eltuki-default-status))) + +(defun eltuki-toggle-status () + (interactive) + (save-excursion + (goto-char (point-min)) + (let ((newstatus (if (string= (eltuki-get-status) "draft") + " publish" + " draft"))) + (if (re-search-forward "^#\\+STATUS:\\(.*\\)$" nil t) + (replace-match newstatus t t nil 1) + (when (search-forward "\n\n" nil t) + (backward-char)) + (insert "#+STATUS:" newstatus "\n"))))) + +(defun eltuki-get-comment-status () + (save-excursion + (goto-char (point-min)) + (if (re-search-forward + "^#\\+COMMENTSTATUS: \\(open\\|closed\\)$" nil t) + (buffer-substring-no-properties + (match-beginning 1) (match-end 1)) + eltuki-default-comment-status))) + +(defun eltuki-toggle-comment-status () + (interactive) + (save-excursion + (goto-char (point-min)) + (let ((newstatus (if (string= (eltuki-get-comment-status) "closed") + " open" + " closed"))) + (if (re-search-forward "^#\\+COMMENTSTATUS:\\(.*\\)$" nil t) + (replace-match newstatus t t nil 1) + (when (search-forward "\n\n" nil t) + (backward-char)) + (insert "#+COMMENTSTATUS:" newstatus "\n"))))) + +(defun eltuki-slugify-string (str) + (while (string-match "[^a-zA-Z0-9 ]+" str) + (setq str (replace-match "" nil t str))) + (while (string-match " +" str) + (setq str (replace-match "-" nil t str))) + (downcase str)) + +(defun eltuki-get-directory () + (concat + eltuki-blog-dir "/" + (format-time-string "%Y%%2f%m%%2f%d%%2f") + (eltuki-slugify-string (eltuki-get-title)))) + +(defun eltuki-write-content (dir) + (let ((org-export-with-toc nil) + (filename (concat dir "/content"))) + (with-current-buffer (org-export-region-as-html + (point-min) (point-max) t "*eltuki-html*") + (write-region (point-min) (point-max) filename) + (kill-buffer)) + filename)) + +(defun eltuki-write-metadata (dir) + (let ((timestamp (eltuki-get-timestamp)) + (tags (eltuki-get-tags)) + (status (eltuki-get-status)) + (title (eltuki-get-title)) + (name (eltuki-slugify-string (eltuki-get-title))) + (commentstatus (eltuki-get-comment-status)) + (filename (concat dir "/metadata"))) + (with-temp-buffer + (insert "timestamp: " timestamp "\n" + "tags: " tags "\n" + "status: " status "\n" + "title: " title "\n" + "name: " name "\n" + "comment_status: " commentstatus) + (write-region (point-min) (point-max) filename)) + filename)) + +(defun eltuki-save-org (buffer dir) + (let ((filename (concat dir "/post.org"))) + (with-current-buffer buffer + (write-file filename)) + filename)) + +(defun eltuki-git-add (file) + (shell-command (concat "cd " eltuki-blog-dir "; git add '" (expand-file-name file) "'"))) + +(defun eltuki-commit () + (shell-command (concat "cd " eltuki-blog-dir "; git commit -m \"new post: \\\"" (eltuki-get-title) + "\\\"\""))) + +(defun eltuki-finish () + (interactive) + (let ((buffer (or (get-buffer "*eltuki*") + (current-buffer))) + (dest (eltuki-get-directory))) + (unless (file-exists-p dest) + (mkdir dest)) + + (mapc #'eltuki-git-add + (list (eltuki-write-content dest) + (eltuki-write-metadata dest) + (eltuki-save-org buffer dest))) + + (eltuki-commit) + (kill-buffer buffer))) + +(provide 'eltuki) +;;; eltuki.el ends here -- cgit v1.2.3-54-g00ecf