Emacs(Elisp): calculate region and insert. 選択範囲の数式を計算して、次の行にinsertします。数字が羅列されている場合は、加算します。数字や式と自然な文章が混在している場合は、数式のみを計算します。
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
;;; ------------------------------------------------------------ | |
;;; 選択範囲を計算してバッファに出力 | |
;; gist-description: Emacs(Elisp): calculate region and insert. 選択範囲の数式を計算して、次の行にinsertします。数字が羅列されている場合は、加算します。数字や式と自然な文章が混在している場合は、数式のみを計算します。 | |
;; gist-id: b967d6a7441f85aa541d | |
;; gist-name: calculate-region-and-insert.el | |
;; gist-private: nil | |
(defun add-number-grouping (number &optional separator) | |
"Add commas to NUMBER and return it as a string. | |
Optional SEPARATOR is the string to use to separate groups. | |
It defaults to a comma." | |
(let ((num (number-to-string number)) | |
(op (or separator ","))) | |
(while (string-match "\\(.*[0-9]\\)\\([0-9][0-9][0-9].*\\)" num) | |
(setq num (concat | |
(match-string 1 num) op | |
(match-string 2 num)))) | |
num)) | |
(defun calculate-region-and-insert (beg end) | |
"Calculate natural text of region and insert to current buffer. BEG, END." | |
(interactive "r") | |
(let* ((strings (if mark-active | |
(buffer-substring-no-properties beg end) | |
(read-string " Expression: " ""))) | |
(is_num_format (string-match "," (buffer-substring-no-properties beg end))) | |
result) | |
;; 余計なものを取り払って計算の準備 | |
(when mark-active | |
(with-temp-buffer | |
(insert strings) | |
(perform-replace "[\t, ]+" "" nil t nil nil nil (point-min) (point-max)) | |
(perform-replace "\n" "+" nil t nil nil nil (point-min) (point-max)) | |
(perform-replace "[^0-9\\+\\*/\\(\\)^\\.-]" "+" nil t nil nil nil (point-min) (point-max)) | |
(perform-replace "\\++" "+" nil t nil nil nil (point-min) (point-max)) | |
(perform-replace "\\+$" "" nil t nil nil nil (point-min) (point-max)) | |
(perform-replace "^\\++" "" nil t nil nil nil (point-min) (point-max)) | |
(setq strings (buffer-substring-no-properties (point-min) (point-max)))) | |
(goto-char end) | |
(end-of-line) | |
(newline)) | |
(setq result (calc-eval strings)) | |
;; カンマ整形されている計算式だったらカンマ区切りで返す | |
(when is_num_format (setq result (add-number-grouping (string-to-number result) ","))) | |
;; (calc-eval)は、小数点を含んだ式の場合、整数でも末尾にピリオドをつけるので抑止 | |
(when (string-match "\\.$" result) | |
(setq result (substring result 0 (match-beginning 0)))) | |
(insert result))) | |
(global-set-key (kbd "M-c") 'calculate-region-and-insert) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment