Last active
January 13, 2018 03:02
-
-
Save sanryuu/7842967 to your computer and use it in GitHub Desktop.
Emacsでテンプレートから文書を生成する。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; | |
;; ---- how to use -------- | |
;; | |
;; M-x fit:generate | |
;; | |
;; ---- setting templete and varibale -------- | |
;; | |
;; (setq template-dir "~/template") | |
;; | |
;; (fit:register-template "経営会議" "management-meeting" fit:week-tuesday) | |
;; (fit:register-template "開発会議" "develop-meeting" fit:week-friday) | |
;; (fit:register-variable "name" "田中") | |
;; | |
;; ---- template file examplete --------- | |
;; ----------- | |
;; 参加者各位。 | |
;; お疲れさまです、#{$name}です。 | |
;; | |
;; #{%m/%d}の会議のお知らせです。 | |
;; ----------- | |
;; it save in template-dir/file-name | |
;; | |
(require 'cl) | |
(require 'popup) | |
(defcustom template-dir "~/.template" | |
"Template Directory Path") | |
(defconst fit:week-sunday 0) | |
(defconst fit:week-monday 1) | |
(defconst fit:week-tuesday 2) | |
(defconst fit:week-wednesday 3) | |
(defconst fit:week-thursday 4) | |
(defconst fit:week-friday 5) | |
(defconst fit:week-saturday 6) | |
(setq fit:for-fill-variable (make-hash-table :test #'equal)) | |
(setq fit:for-fill-time (make-hash-table :test #'equal)) | |
(setq fit:template-alias (make-hash-table :test #'equal)) | |
(defun fit:register-template (display-name file-name &optional week) | |
"テンプレートを登録する | |
使用: (fit:register-template \"開発会議\" \"business\" fit:week-friday) " | |
(puthash display-name file-name fit:template-alias) | |
(puthash file-name week fit:for-fill-time)) | |
(defun fit:register-variable (variable-name variable-value) | |
"変数を登録する" | |
(puthash variable-name variable-value fit:for-fill-variable)) | |
(defun fit:load-template-with-menu () | |
"popup-menuからの選択テンプレートを読み込んで | |
新しいバッファに展開する。" | |
(interactive) | |
;; -- 作成するメールの選択 -- | |
(let (alias-list selected-template) | |
(maphash #'(lambda (key value) | |
(add-to-list 'alias-list (format "%s" key))) | |
fit:template-alias) | |
(setq selected-template | |
(gethash | |
(popup-menu* alias-list :margin t) | |
fit:template-alias)) | |
(fit:load-template selected-template) | |
selected-template)) | |
(defun fit:load-template (template-file) | |
"Load template for fill variable | |
This function load template and, | |
insert new buffer" | |
;; -- テンプレートファイルの処理 -- | |
(with-temp-buffer | |
(insert-file-contents | |
(format "%s/%s.txt" template-dir template-file)) | |
;; -- テンプレートファイルを開いた後の処理 -- | |
(setq template-string (buffer-string)) | |
) | |
(kill-buffer (get-buffer-create "*Filled Template*")) | |
(switch-to-buffer (get-buffer-create "*Filled Template*")) | |
(insert template-string) | |
(goto-char (point-min))) | |
;;変数の置換 | |
(defun fill-in-variable () | |
"This function is replace variable to template from hash" | |
(interactive) | |
(let (variable-name fill current-point) | |
(setq current-point (point)) | |
(goto-char (point-min)) | |
(while | |
(re-search-forward "#{\\(\\$\\(.*\\)\\)}" nil t) | |
(setq variable-name (match-string 2)) | |
(setq fill (gethash variable-name fit:for-fill-variable)) | |
(if fill | |
(replace-match fill) | |
(message (concat "variable \"" variable-name "\" is not found")) | |
)) | |
(goto-char current-point))) | |
;;日付けの置換 | |
(defun fill-in-format-time (&optional time) | |
"This function is replace #{format-date} to fromat-time | |
example: (fill-in-format-time(current-time)) | |
xx#{%m/%d}xx -> xx12/25xx | |
defuault time is (curren-time)" | |
(interactive) | |
(let (current-point) | |
(setq current-point (point)) | |
(goto-char (point-min)) | |
(while | |
(re-search-forward "#{\\([^$}]*\\)}" nil t) | |
(replace-match (format-time-string (match-string 1) time))) | |
(goto-char current-point))) | |
(defun get-future-time (sec minute hour day month year) | |
"引数時間後のencode-timeを取得する | |
example: (apply 'get-future-time '(0 0 0 0 0 1)) | |
result : (21605 53214) | |
params, | |
sec 0から59の整数で表した分内の秒数。 | |
minute 0から59の整数で表した時内の分数。 | |
hour 0から23の整数で表した日内の時。 | |
day 1から31の整数で表した月内の日。 | |
month 1から12の整数で表した年内の月。 | |
year 年。 典型的には1900より大きい。" | |
(let (time) | |
(setq time (decode-time (current-time))) | |
(setf (elt time 0) (+ (elt time 0) sec)) | |
(setf (elt time 1) (+ (elt time 1) minute)) | |
(setf (elt time 2) (+ (elt time 2) hour)) | |
(setf (elt time 3) (+ (elt time 3) day)) | |
(setf (elt time 4) (+ (elt time 4) month)) | |
(setf (elt time 5) (+ (elt time 5) year)) | |
(apply 'encode-time time) | |
)) | |
(defun fit:fill-in-template () | |
(interactive) | |
(fill-in-variable) | |
;;時間関係の何か | |
) | |
(defun fit:count-next-day-of-week(taget-week day-week) | |
"次のtaget-weekまでの日数を求める。当日を0換算" | |
(let ((week 7)) | |
(mod (- taget-week day-week) week))) | |
(defun fit:generate () | |
"メールの生成" | |
(interactive) | |
(let (convene-week next-convene-time) | |
(setq selected-template (fit:load-template-with-menu)) | |
(fill-in-variable) | |
(setq convene-week (gethash selected-template fit:for-fill-time)) | |
(setq distance-next-concene | |
(fit:count-next-day-of-week | |
convene-week (string-to-int (format-time-string "%w")))) | |
(setq next-convene-time | |
(get-future-time 0 0 0 distance-next-concene 0 0)) | |
(when convene-week | |
(while | |
(re-search-forward "#{\\([^$}]*\\)}" nil t) | |
(replace-match (format-time-string (match-string 1) next-convene-time)) | |
(goto-char (point-min)))))) | |
(require 'fill-in-template) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment