Skip to content

Instantly share code, notes, and snippets.

@sanryuu
Last active January 13, 2018 03:02
Show Gist options
  • Save sanryuu/7842967 to your computer and use it in GitHub Desktop.
Save sanryuu/7842967 to your computer and use it in GitHub Desktop.
Emacsでテンプレートから文書を生成する。
;;
;; ---- 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