123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369 |
- ;;; org-effectiveness.el --- Measuring the personal effectiveness
- ;; Copyright (C) 2013-2018 Free Software Foundation, Inc.
- ;; Author: David Arroyo Menéndez <davidam@es.gnu.org>
- ;; Keywords: effectiveness, plot
- ;; Homepage: http://orgmode.org
- ;;
- ;; This file is not part of GNU Emacs, yet.
- ;;
- ;; GNU Emacs 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.
- ;; GNU Emacs 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 GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;; Commentary:
- ;; This file implements functions to measure the effectiveness in org.
- ;; Org-mode doesn't load this module by default - if this is not what
- ;; you want, configure the variable `org-modules'. Thanks to #emacs-es
- ;; irc channel for your support.
- ;;; Code:
- (require 'org)
- (defcustom org-effectiveness-max-todo 50
- "This variable is useful to advice to the user about
- many TODO pending"
- :type 'integer
- :group 'org-effectiveness)
- (defun org-effectiveness-advice()
- "Advicing about a possible excess of TODOS"
- (interactive)
- (save-excursion
- (goto-char (point-min))
- (if (< org-effectiveness-max-todo (count-matches "* TODO"))
- (message "An excess of TODOS!"))))
- ;; Check advice starting an org file
- (add-hook 'org-mode-hook 'org-effectiveness-advice)
- (defun org-effectiveness-count-keyword(keyword)
- "Print a message with the number of keyword outline in the current buffer"
- (interactive "sKeyword: ")
- (save-excursion
- (goto-char (point-min))
- (message "Number of %s: %d" keyword (count-matches (concat "* " keyword)))))
- (defun org-effectiveness-count-todo()
- "Print a message with the number of todo tasks in the current buffer"
- (interactive)
- (save-excursion
- (goto-char (point-min))
- (message "Number of TODO: %d" (count-matches "* TODO"))))
- (defun org-effectiveness-count-done()
- "Print a message with the number of done tasks in the current buffer"
- (interactive)
- (save-excursion
- (goto-char (point-min))
- (message "Number of DONE: %d" (count-matches "* DONE"))))
- (defun org-effectiveness-count-canceled()
- "Print a message with the number of canceled tasks in the current buffer"
- (interactive)
- (save-excursion
- (goto-char (point-min))
- (message "Number of Canceled: %d" (count-matches "* CANCEL+ED"))))
- (defun org-effectiveness-count-task()
- "Print a message with the number of tasks and subtasks in the current buffer"
- (interactive)
- (save-excursion
- (goto-char (point-min))
- (message "Number of tasks: %d" (count-matches "^*"))))
- (defun org-effectiveness()
- "Returns the effectiveness in the current org buffer"
- (interactive)
- (save-excursion
- (goto-char (point-min))
- (let ((done (float (count-matches "* DONE.*\n.*")))
- (canc (float (count-matches "* CANCEL+ED.*\n.*"))))
- (if (and (= done canc) (zerop done))
- (setq effectiveness 0)
- (setq effectiveness (* 100 (/ done (+ done canc)))))
- (message "Effectiveness: %f" effectiveness))))
- (defun org-effectiveness-keywords-in-date(keyword date)
- (interactive "sKeyword: \nsDate: " keyword date)
- (setq count (count-matches (concat keyword ".*\n.*" date)))
- (message (concat "%sS: %d" keyword count)))
- (defun org-effectiveness-dones-in-date(date &optional notmessage)
- (interactive "sGive me a date: " date)
- (save-excursion
- (goto-char (point-min))
- (let ((count (count-matches (concat "DONE.*\n.*" date))))
- (if (eq notmessage 1)
- (message "%d" count)
- (message "DONES: %d " count)))))
- (defun org-effectiveness-todos-in-date(date)
- (interactive "sGive me a date: " date)
- (save-excursion
- (goto-char (point-min))
- (setq count (count-matches (concat "TODO.*\n.*" date)))
- (message "TODOS: %d" count)))
- (defun org-effectiveness-canceled-in-date(date)
- (interactive "sGive me a date: " date)
- (save-excursion
- (goto-char (point-min))
- (setq count (count-matches (concat "CANCEL+ED.*\n.*" date)))
- (message "CANCELEDS: %d" count)))
- (defun org-effectiveness-ntasks-in-date(date &optional notmessage)
- (interactive "sGive me a date: " date)
- (save-excursion
- (goto-char (point-min))
- (let ((tasks (float (count-matches (concat "^*.*\n.*" date)))))
- (message "%d" tasks))))
- (defun org-effectiveness-in-date(date &optional notmessage)
- (interactive "sGive me a date: " date)
- (save-excursion
- (goto-char (point-min))
- (let ((done (float (count-matches (concat "* DONE.*\n.*" date))))
- (canc (float (count-matches (concat "* CANCEL+ED.*\n.*" date)))))
- (if (and (= done canc) (zerop done))
- (setq effectiveness 0)
- (setq effectiveness (* 100 (/ done (+ done canc)))))
- (if (eq notmessage 1)
- (message "%d" effectiveness)
- (message "Effectiveness: %d " effectiveness)))))
- (defun org-effectiveness-month-to-string (m)
- (if (< m 10)
- (concat "0" (number-to-string m))
- (number-to-string m)))
- (defun org-effectiveness-plot(startdate enddate &optional save)
- (interactive "sGive me the start date: \nsGive me the end date: " startdate enddate)
- (setq dates (org-effectiveness-check-dates startdate enddate))
- (setq syear (cadr (assq 'startyear dates)))
- (setq smonth (cadr (assq 'startmonth dates)))
- (setq eyear (cadr (assq 'endyear dates)))
- (setq emonth (assq 'endmonth dates))
- ;; Checking the format of the dates
- (if (not (string-match "[0-9][0-9][0-9][0-9]-[0-9][0-9]" startdate))
- (message "The start date must have the next format YYYY-MM"))
- (if (not (string-match "[0-9][0-9][0-9][0-9]-[0-9][0-9]" enddate))
- (message "The end date must have the next format YYYY-MM"))
- ;; Checking if startdate < enddate
- (if (string-match "^[0-9][0-9][0-9][0-9]" startdate)
- (setq startyear (string-to-number (match-string 0 startdate))))
- (if (string-match "[0-9][0-9]$" startdate)
- (setq startmonth (string-to-number (match-string 0 startdate))))
- (if (string-match "^[0-9][0-9][0-9][0-9]" enddate)
- (setq endyear (string-to-number (match-string 0 enddate))))
- (if (string-match "[0-9][0-9]$" enddate)
- (setq endmonth (string-to-number (match-string 0 enddate))))
- (if (> startyear endyear)
- (message "The start date must be before that end date"))
- (if (and (= startyear endyear) (> startmonth endmonth))
- (message "The start date must be before that end date"))
- ;; Create a file
- (let ((month startmonth)
- (year startyear)
- (str ""))
- (while (or (> endyear year) (and (= endyear year) (>= endmonth month)))
- (setq str (concat str (number-to-string year) "-" (org-effectiveness-month-to-string month) " " (org-effectiveness-in-date (concat (number-to-string year) "-" (org-effectiveness-month-to-string month)) 1) "\n"))
- (if (= month 12)
- (progn
- (setq year (+ 1 year))
- (setq month 1))
- (setq month (+ 1 month))))
- (write-region str nil "/tmp/org-effectiveness"))
- ;; Create the bar graph
- (if (eq save t)
- (setq strplot "/usr/bin/gnuplot -e 'set term png; set output \"/tmp/org-effectiveness.png\"; plot \"/tmp/org-effectiveness\" using 2:xticlabels(1) with histograms' -p")
- (setq strplot "/usr/bin/gnuplot -e 'plot \"/tmp/org-effectiveness\" using 2:xticlabels(1) with histograms' -p"))
- (if (file-exists-p "/usr/bin/gnuplot")
- (call-process "/bin/bash" nil t nil "-c" strplot)
- (message "gnuplot is not installed")))
- (defun org-effectiveness-plot-save(startdate enddate &optional save)
- (interactive "sGive me the start date: \nsGive me the end date: " startdate enddate)
- (org-effectiveness-plot startdate enddate t))
- ;; (defun org-effectiveness-plot(startdate enddate)
- (defun org-effectiveness-ascii-bar(n &optional label)
- "Print a bar with the percentage from 0 to 100 printed in ascii"
- (interactive "nPercentage: \nsLabel: ")
- (if (or (< n 0) (> n 100))
- (message "The percentage must be between 0 to 100")
- (let ((x 0)
- (y 0)
- (z 0))
- (insert (format "\n### %s ###" label))
- (insert "\n-")
- (while (< x n)
- (insert "-")
- (setq x (+ x 1)))
- (insert "+\n")
- (insert (format "%d" n))
- (if (> n 10)
- (setq y (+ y 1)))
- (while (< y n)
- (insert " ")
- (setq y (+ y 1)))
- (insert "|\n")
- (insert "-")
- (while (< z n)
- (insert "-")
- (setq z (+ z 1)))
- (insert "+"))))
- (defun org-effectiveness-html-bar(n &optional label)
- "Print a bar with the percentage from 0 to 100 printed in html"
- (interactive "nPercentage: \nsLabel: ")
- (if (or (< n 0) (> n 100))
- (message "The percentage must be between 0 to 100")
- (let ((x 0)
- (y 0)
- (z 0))
- (insert (format "\n<div class='percentage-%d'>%d</div>" n n))
- )))
- (defun org-effectiveness-check-dates (startdate enddate)
- "Generate a list with ((startyear startmonth) (endyear endmonth))"
- (setq str nil)
- (if (not (string-match "[0-9][0-9][0-9][0-9]-[0-9][0-9]" startdate))
- (setq str "The start date must have the next format YYYY-MM"))
- (if (not (string-match "[0-9][0-9][0-9][0-9]-[0-9][0-9]" enddate))
- (setq str "The end date must have the next format YYYY-MM"))
- ;; Checking if startdate < enddate
- (if (string-match "^[0-9][0-9][0-9][0-9]" startdate)
- (setq startyear (string-to-number (match-string 0 startdate))))
- (if (string-match "[0-9][0-9]$" startdate)
- (setq startmonth (string-to-number (match-string 0 startdate))))
- (if (string-match "^[0-9][0-9][0-9][0-9]" enddate)
- (setq endyear (string-to-number (match-string 0 enddate))))
- (if (string-match "[0-9][0-9]$" enddate)
- (setq endmonth (string-to-number (match-string 0 enddate))))
- (if (> startyear endyear)
- (setq str "The start date must be before that end date"))
- (if (and (= startyear endyear) (> startmonth endmonth))
- (setq str "The start date must be before that end date"))
- (if str
- (message str)
- ;; (list (list startyear startmonth) (list endyear endmonth))))
- (list (list 'startyear startyear) (list 'startmonth startmonth) (list 'endyear endyear) (list 'endmonth endmonth))))
- (defun org-effectiveness-plot-ascii (startdate enddate)
- (interactive "sGive me the start date: \nsGive me the end date: " startdate enddate)
- (setq dates (org-effectiveness-check-dates startdate enddate))
- (let ((syear (cadr (assq 'startyear dates)))
- (smonth (cadr (assq 'startmonth dates)))
- (year (cadr (assq 'startyear dates)))
- (month (cadr (assq 'startmonth dates)))
- (emonth (cadr (assq 'endmonth dates)))
- (eyear (cadr (assq 'endyear dates)))
- (buffer (current-buffer))
- (str ""))
- (while (or (> eyear year) (and (= eyear year) (>= emonth month)))
- (setq str (org-effectiveness-in-date (concat (number-to-string year) "-" (org-effectiveness-month-to-string month)) 1))
- (switch-to-buffer "*org-effectiveness*")
- (org-effectiveness-ascii-bar (string-to-number str) (format "%s-%s" year month))
- (switch-to-buffer buffer)
- (if (eq month 12)
- (progn
- (setq year (+ 1 year))
- (setq month 1))
- (setq month (+ 1 month)))))
- (switch-to-buffer "*org-effectiveness*"))
- (defun org-effectiveness-plot-ascii-ntasks (startdate enddate)
- (interactive "sGive me the start date: \nsGive me the end date: " startdate enddate)
- (setq dates (org-effectiveness-check-dates startdate enddate))
- (let ((syear (cadr (assq 'startyear dates)))
- (smonth (cadr (assq 'startmonth dates)))
- (year (cadr (assq 'startyear dates)))
- (month (cadr (assq 'startmonth dates)))
- (emonth (cadr (assq 'endmonth dates)))
- (eyear (cadr (assq 'endyear dates)))
- (buffer (current-buffer))
- (str ""))
- (while (or (> eyear year) (and (= eyear year) (>= emonth month)))
- (setq str (org-effectiveness-ntasks-in-date (concat (number-to-string year) "-" (org-effectiveness-month-to-string month)) 1))
- (switch-to-buffer "*org-effectiveness*")
- (org-effectiveness-ascii-bar (string-to-number str) (format "%s-%s" year month))
- (switch-to-buffer buffer)
- (if (eq month 12)
- (progn
- (setq year (+ 1 year))
- (setq month 1))
- (setq month (+ 1 month)))))
- (switch-to-buffer "*org-effectiveness*"))
- (defun org-effectiveness-plot-ascii-dones (startdate enddate)
- (interactive "sGive me the start date: \nsGive me the end date: " startdate enddate)
- (setq dates (org-effectiveness-check-dates startdate enddate))
- (let ((syear (cadr (assq 'startyear dates)))
- (smonth (cadr (assq 'startmonth dates)))
- (year (cadr (assq 'startyear dates)))
- (month (cadr (assq 'startmonth dates)))
- (emonth (cadr (assq 'endmonth dates)))
- (eyear (cadr (assq 'endyear dates)))
- (buffer (current-buffer))
- (str ""))
- (while (or (> eyear year) (and (= eyear year) (>= emonth month)))
- (setq str (org-effectiveness-dones-in-date (concat (number-to-string year) "-" (org-effectiveness-month-to-string month)) 1))
- (switch-to-buffer "*org-effectiveness*")
- (org-effectiveness-ascii-bar (string-to-number str) (format "%s-%s" year month))
- (switch-to-buffer buffer)
- (if (eq month 12)
- (progn
- (setq year (+ 1 year))
- (setq month 1))
- (setq month (+ 1 month)))))
- (switch-to-buffer "*org-effectiveness*"))
- (defun org-effectiveness-plot-html (startdate enddate)
- "Print html bars about the effectiveness in a buffer"
- (interactive "sGive me the start date: \nsGive me the end date: " startdate enddate)
- (setq dates (org-effectiveness-check-dates startdate enddate))
- (let ((syear (cadr (assq 'startyear dates)))
- (smonth (cadr (assq 'startmonth dates)))
- (year (cadr (assq 'startyear dates)))
- (month (cadr (assq 'startmonth dates)))
- (emonth (cadr (assq 'endmonth dates)))
- (eyear (cadr (assq 'endyear dates)))
- (buffer (current-buffer))
- (str ""))
- (switch-to-buffer "*org-effectiveness-html*")
- (insert "<html><head><title>Graphbar</title><meta http-equiv='Content-type' content='text/html; charset=utf-8'><link rel='stylesheet' type='text/css' href='graphbar.css' title='graphbar'></head><body>")
- (while (or (> eyear year) (and (= eyear year) (>= emonth month)))
- (setq str (org-effectiveness-in-date (concat (number-to-string year) "-" (org-effectiveness-month-to-string month)) 1))
- (switch-to-buffer "*org-effectiveness-html*")
- (org-effectiveness-html-bar (string-to-number str) (format "%s-%s" year month))
- (switch-to-buffer buffer)
- (format "%s-%s" year month)
- (if (eq month 12)
- (progn
- (setq year (+ 1 year))
- (setq month 1))
- (setq month (+ 1 month))))
- (switch-to-buffer "*org-effectiveness-html*")
- (insert "</body></html>")))
- (provide 'org-effectiveness)
|