;;; timeclock.el --- mode for keeping track of how much you work
-;; Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
+;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+;; 2008, 2009, 2010 Free Software Foundation, Inc.
;; Author: John Wiegley <johnw@gnu.org>
;; Created: 25 Mar 1999
-;; Version: 2.6
+;; Version: 2.6.1
;; Keywords: calendar data
;; This file is part of GNU Emacs.
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
-;; any later version.
+;; 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
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;; User Variables:
(defcustom timeclock-file (convert-standard-filename "~/.timelog")
- "*The file used to store timeclock data in."
+ "The file used to store timeclock data in."
:type 'file
:group 'timeclock)
(defcustom timeclock-workday (* 8 60 60)
- "*The length of a work period."
+ "The length of a work period in seconds."
:type 'integer
:group 'timeclock)
(defcustom timeclock-relative t
- "*Whether to maken reported time relative to `timeclock-workday'.
+ "Whether to make reported time relative to `timeclock-workday'.
For example, if the length of a normal workday is eight hours, and you
work four hours on Monday, then the amount of time \"remaining\" on
Tuesday is twelve hours -- relative to an averaged work period of
:group 'timeclock)
(defcustom timeclock-get-project-function 'timeclock-ask-for-project
- "*The function used to determine the name of the current project.
+ "The function used to determine the name of the current project.
When clocking in, and no project is specified, this function will be
called to determine what is the current project to be worked on.
If this variable is nil, no questions will be asked."
:group 'timeclock)
(defcustom timeclock-get-reason-function 'timeclock-ask-for-reason
- "*A function used to determine the reason for clocking out.
+ "A function used to determine the reason for clocking out.
When clocking out, and no reason is specified, this function will be
called to determine what is the reason.
If this variable is nil, no questions will be asked."
:group 'timeclock)
(defcustom timeclock-get-workday-function nil
- "*A function used to determine the length of today's workday.
+ "A function used to determine the length of today's workday.
The first time that a user clocks in each day, this function will be
called to determine what is the length of the current workday. If
the return value is nil, or equal to `timeclock-workday', nothing special
:group 'timeclock)
(defcustom timeclock-ask-before-exiting t
- "*If non-nil, ask if the user wants to clock out before exiting Emacs.
+ "If non-nil, ask if the user wants to clock out before exiting Emacs.
This variable only has effect if set with \\[customize]."
:set (lambda (symbol value)
(if value
(defvar timeclock-modeline-display)
(defcustom timeclock-use-display-time t
- "*If non-nil, use `display-time-hook' for doing modeline updates.
+ "If non-nil, use `display-time-hook' for doing modeline updates.
The advantage of this is that one less timer has to be set running
amok in Emacs' process space. The disadvantage is that it requires
you to have `display-time' running. If you don't want to use
:require 'time)
(defcustom timeclock-first-in-hook nil
- "*A hook run for the first \"in\" event each day.
+ "A hook run for the first \"in\" event each day.
Note that this hook is run before recording any events. Thus the
value of `timeclock-hours-today', `timeclock-last-event' and the
return value of function `timeclock-last-period' are relative previous
:group 'timeclock)
(defcustom timeclock-load-hook nil
- "*Hook that gets run after timeclock has been loaded."
+ "Hook that gets run after timeclock has been loaded."
:type 'hook
:group 'timeclock)
(defcustom timeclock-in-hook nil
- "*A hook run every time an \"in\" event is recorded."
+ "A hook run every time an \"in\" event is recorded."
:type 'hook
:group 'timeclock)
(defcustom timeclock-day-over-hook nil
- "*A hook that is run when the workday has been completed.
+ "A hook that is run when the workday has been completed.
This hook is only run if the current time remaining is being displayed
in the modeline. See the variable `timeclock-modeline-display'."
:type 'hook
:group 'timeclock)
(defcustom timeclock-out-hook nil
- "*A hook run every time an \"out\" event is recorded."
+ "A hook run every time an \"out\" event is recorded."
:type 'hook
:group 'timeclock)
(defcustom timeclock-done-hook nil
- "*A hook run every time a project is marked as completed."
+ "A hook run every time a project is marked as completed."
:type 'hook
:group 'timeclock)
(defcustom timeclock-event-hook nil
- "*A hook run every time any event is recorded."
+ "A hook run every time any event is recorded."
:type 'hook
:group 'timeclock)
This value is not accurate enough to be useful by itself. Rather,
call `timeclock-workday-elapsed', to determine how much time has been
worked so far today. Also, if `timeclock-relative' is nil, this value
-will be the same as `timeclock-discrepancy'.") ; ? gm
+will be the same as `timeclock-discrepancy'.")
+
+(defvar timeclock-use-elapsed nil
+ "Non-nil if the modeline should display time elapsed, not remaining.")
(defvar timeclock-last-period nil
"Integer representing the number of seconds in the last period.
;; Update immediately so there is a visible change
;; on calling this function.
(if display-time-mode (timeclock-update-modeline)
- (message "Activate `display-time-mode' to see \
-timeclock information"))
+ (message "Activate `display-time-mode' or turn off \
+`timeclock-use-display-time' to see timeclock information"))
(add-hook 'display-time-hook 'timeclock-update-modeline))
(setq timeclock-update-timer
(run-at-time nil 60 'timeclock-update-modeline))))
(defun timeclock-in (&optional arg project find-project)
"Clock in, recording the current time moment in the timelog.
With a numeric prefix ARG, record the fact that today has only that
-many hours in it to be worked. If arg is a non-numeric prefix arg
+many hours in it to be worked. If ARG is a non-numeric prefix argument
\(non-nil, but not a number), 0 is assumed (working on a holiday or
weekend). *If not called interactively, ARG should be the number of
_seconds_ worked today*. This feature only has effect the first time
(setq timeclock-discrepancy
(- (or timeclock-discrepancy 0) workday))
(if (not (= workday timeclock-workday))
- (timeclock-log "h" (and (numberp arg)
- (number-to-string arg))))))
+ (timeclock-log "h" (number-to-string
+ (/ workday (if (zerop (% workday (* 60 60)))
+ 60 60.0) 60))))))
(timeclock-log "i" (or project
(and timeclock-get-project-function
- (or find-project (interactive-p))
+ (or find-project
+ (called-interactively-p 'interactive))
(funcall timeclock-get-project-function))))
(run-hooks 'timeclock-in-hook)))
(if arg "O" "o")
(or reason
(and timeclock-get-reason-function
- (or find-reason (interactive-p))
+ (or find-reason (called-interactively-p 'interactive))
(funcall timeclock-get-reason-function))))
(run-hooks 'timeclock-out-hook)
(if arg
If TODAY-ONLY is non-nil, the display will be relative only to time
worked today, ignoring the time worked on previous days."
(interactive "P")
- (let ((remainder (timeclock-workday-remaining)) ; today-only?
+ (let ((remainder (timeclock-workday-remaining
+ (or today-only
+ (not timeclock-relative))))
(last-in (equal (car timeclock-last-event) "i"))
status)
(setq status
(if (> remainder 0)
"remaining" "over")
(timeclock-when-to-leave-string show-seconds today-only)))
- (if (interactive-p)
- (message status)
+ (if (called-interactively-p 'interactive)
+ (message "%s" status)
status)))
;;;###autoload
working on."
(interactive "P")
(timeclock-out arg)
- (timeclock-in nil project (interactive-p)))
+ (timeclock-in nil project (called-interactively-p 'interactive)))
;;;###autoload
(defun timeclock-query-out ()
(let ((string (timeclock-seconds-to-string
(timeclock-workday-remaining today-only)
show-seconds t)))
- (if (interactive-p)
- (message string)
+ (if (called-interactively-p 'interactive)
+ (message "%s" string)
string)))
(defsubst timeclock-workday-elapsed ()
(interactive)
(let ((string (timeclock-seconds-to-string (timeclock-workday-elapsed)
show-seconds)))
- (if (interactive-p)
- (message string)
+ (if (called-interactively-p 'interactive)
+ (message "%s" string)
string)))
(defsubst timeclock-time-to-seconds (time)
"Convert TIME to a floating point number."
(+ (* (car time) 65536.0)
(cadr time)
- (/ (or (car (cdr (cdr time))) 0) 1000000.0)))
+ (/ (or (nth 2 time) 0) 1000000.0)))
(defsubst timeclock-seconds-to-time (seconds)
"Convert SECONDS (a floating point number) to an Emacs time structure."
(if show-seconds
(format-time-string "%-I:%M:%S %p" then)
(format-time-string "%-I:%M %p" then))))
- (if (interactive-p)
- (message string)
+ (if (called-interactively-p 'interactive)
+ (message "%s" string)
string)))
+(defun timeclock-make-hours-explicit (old-default)
+ "Specify all workday lengths in `timeclock-file'.
+OLD-DEFAULT hours are set for every day that has no number indicated."
+ (interactive "P")
+ (if old-default (setq old-default (prefix-numeric-value old-default))
+ (error "`timelog-make-hours-explicit' requires an explicit argument"))
+ (let ((extant-timelog (find-buffer-visiting timeclock-file))
+ current-date)
+ (with-current-buffer (find-file-noselect timeclock-file t)
+ (unwind-protect
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (while (progn (skip-chars-forward "\n") (not (eobp)))
+ ;; This is just a variant of `timeclock-moment-regexp'.
+ (unless (looking-at
+ (concat "^\\([bhioO]\\) \\([0-9]+/[0-9]+/[0-9]+\\) "
+ "\\([0-9]+:[0-9]+:[0-9]+\\)"))
+ (error "Can't parse `%s'" timeclock-file))
+ (let ((this-date (match-string 2)))
+ (unless (or (and current-date
+ (string= this-date current-date))
+ (string= (match-string 1) "h"))
+ (insert (format "h %s %s %s\n" (match-string 2)
+ (match-string 3) old-default)))
+ (if (string-match "^[ih]" (match-string 1)) ; ignore logouts
+ (setq current-date this-date)))
+ (forward-line))
+ (save-buffer)))
+ (unless extant-timelog (kill-buffer (current-buffer)))))))
+
;;; Internal Functions:
(defvar timeclock-project-list nil)
(defvar timeclock-last-project nil)
(defun timeclock-completing-read (prompt alist &optional default)
- "A version of `completing-read' that works on both Emacs and XEmacs."
+ "A version of `completing-read' that works on both Emacs and XEmacs.
+PROMPT, ALIST and DEFAULT are used for the PROMPT, COLLECTION and DEF
+arguments of `completing-read'."
(if (featurep 'xemacs)
(let ((str (completing-read prompt alist)))
- (if (or (null str) (= (length str) 0))
+ (if (or (null str) (zerop (length str)))
default
str))
(completing-read prompt alist nil nil nil nil default)))
(defun timeclock-ask-for-project ()
"Ask the user for the project they are clocking into."
(timeclock-completing-read
- (format "Clock into which project (default \"%s\"): "
+ (format "Clock into which project (default %s): "
(or timeclock-last-project
(car timeclock-project-list)))
(mapcar 'list timeclock-project-list)
The value of `timeclock-relative' affects the display as described in
that variable's documentation."
(interactive)
- (let ((remainder (timeclock-workday-remaining (not timeclock-relative)))
+ (let ((remainder
+ (if timeclock-use-elapsed
+ (timeclock-workday-elapsed)
+ (timeclock-workday-remaining (not timeclock-relative))))
(last-in (equal (car timeclock-last-event) "i")))
(when (and (< remainder 0)
(not (and timeclock-day-over
"Log the event CODE to the timeclock log, at the time of call.
If PROJECT is a string, it represents the project which the event is
being logged for. Normally only \"in\" events specify a project."
- (with-current-buffer (find-file-noselect timeclock-file)
- (goto-char (point-max))
- (if (not (bolp))
- (insert "\n"))
- (let ((now (current-time)))
- (insert code " "
- (format-time-string "%Y/%m/%d %H:%M:%S" now)
- (or (and project
- (stringp project)
- (> (length project) 0)
- (concat " " project))
- "")
- "\n")
- (if (equal (downcase code) "o")
- (setq timeclock-last-period
- (- (timeclock-time-to-seconds now)
- (timeclock-time-to-seconds
- (cadr timeclock-last-event)))
- timeclock-discrepancy
- (+ timeclock-discrepancy
- timeclock-last-period)))
- (setq timeclock-last-event (list code now project)))
- (save-buffer)
- (run-hooks 'timeclock-event-hook)
- (kill-buffer (current-buffer))))
+ (let ((extant-timelog (find-buffer-visiting timeclock-file)))
+ (with-current-buffer (find-file-noselect timeclock-file t)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-max))
+ (if (not (bolp))
+ (insert "\n"))
+ (let ((now (current-time)))
+ (insert code " "
+ (format-time-string "%Y/%m/%d %H:%M:%S" now)
+ (or (and (stringp project)
+ (> (length project) 0)
+ (concat " " project))
+ "")
+ "\n")
+ (if (equal (downcase code) "o")
+ (setq timeclock-last-period
+ (- (timeclock-time-to-seconds now)
+ (timeclock-time-to-seconds
+ (cadr timeclock-last-event)))
+ timeclock-discrepancy
+ (+ timeclock-discrepancy
+ timeclock-last-period)))
+ (setq timeclock-last-event (list code now project)))))
+ (save-buffer)
+ (unless extant-timelog (kill-buffer (current-buffer)))))
+ (run-hooks 'timeclock-event-hook))
(defvar timeclock-moment-regexp
(concat "\\([bhioO]\\)\\s-+"
timeclock-last-period))
(defsubst timeclock-entry-length (entry)
+ "Return the length of ENTRY in seconds."
(- (timeclock-time-to-seconds (cadr entry))
(timeclock-time-to-seconds (car entry))))
(defsubst timeclock-entry-begin (entry)
+ "Return the start time of ENTRY."
(car entry))
(defsubst timeclock-entry-end (entry)
+ "Return the end time of ENTRY."
(cadr entry))
(defsubst timeclock-entry-project (entry)
+ "Return the project of ENTRY."
(nth 2 entry))
(defsubst timeclock-entry-comment (entry)
+ "Return the comment of ENTRY."
(nth 3 entry))
-
(defsubst timeclock-entry-list-length (entry-list)
+ "Return the total length of ENTRY-LIST in seconds."
(let ((length 0))
- (while entry-list
- (setq length (+ length (timeclock-entry-length (car entry-list))))
- (setq entry-list (cdr entry-list)))
+ (dolist (entry entry-list)
+ (setq length (+ length (timeclock-entry-length entry))))
length))
(defsubst timeclock-entry-list-begin (entry-list)
+ "Return the start time of the first element of ENTRY-LIST."
(timeclock-entry-begin (car entry-list)))
(defsubst timeclock-entry-list-end (entry-list)
+ "Return the end time of the last element of ENTRY-LIST."
(timeclock-entry-end (car (last entry-list))))
(defsubst timeclock-entry-list-span (entry-list)
+ "Return the total time in seconds spanned by ENTRY-LIST."
(- (timeclock-time-to-seconds (timeclock-entry-list-end entry-list))
(timeclock-time-to-seconds (timeclock-entry-list-begin entry-list))))
(defsubst timeclock-entry-list-break (entry-list)
+ "Return the total break time (span - length) in ENTRY-LIST."
(- (timeclock-entry-list-span entry-list)
(timeclock-entry-list-length entry-list)))
(defsubst timeclock-entry-list-projects (entry-list)
- (let (projects)
- (while entry-list
- (let ((project (timeclock-entry-project (car entry-list))))
- (if projects
- (add-to-list 'projects project)
- (setq projects (list project))))
- (setq entry-list (cdr entry-list)))
+ "Return a list of all the projects in ENTRY-LIST."
+ (let (projects proj)
+ (dolist (entry entry-list)
+ (setq proj (timeclock-entry-project entry))
+ (if projects
+ (add-to-list 'projects proj)
+ (setq projects (list proj))))
projects))
-
(defsubst timeclock-day-required (day)
+ "Return the required length of DAY in seconds, default `timeclock-workday'."
(or (car day) timeclock-workday))
(defsubst timeclock-day-length (day)
+ "Return the actual length of DAY in seconds."
(timeclock-entry-list-length (cdr day)))
(defsubst timeclock-day-debt (day)
+ "Return the debt (required - actual) associated with DAY, in seconds."
(- (timeclock-day-required day)
(timeclock-day-length day)))
(defsubst timeclock-day-begin (day)
+ "Return the start time of DAY."
(timeclock-entry-list-begin (cdr day)))
(defsubst timeclock-day-end (day)
+ "Return the end time of DAY."
(timeclock-entry-list-end (cdr day)))
(defsubst timeclock-day-span (day)
+ "Return the span of DAY."
(timeclock-entry-list-span (cdr day)))
(defsubst timeclock-day-break (day)
+ "Return the total break time of DAY."
(timeclock-entry-list-break (cdr day)))
(defsubst timeclock-day-projects (day)
- (timeclock-entry-list-projects (cdr day)))
+ "Return a list of all the projects in DAY."
+ (timeclock-entry-list-projects (cddr day)))
(defmacro timeclock-day-list-template (func)
+ "Template for summing the result of FUNC on each element of DAY-LIST."
`(let ((length 0))
(while day-list
- (setq length (+ length (,(eval func) (car day-list))))
- (setq day-list (cdr day-list)))
+ (setq length (+ length (,(eval func) (car day-list)))
+ day-list (cdr day-list)))
length))
(defun timeclock-day-list-required (day-list)
+ "Return total required length of DAY-LIST, in seconds."
(timeclock-day-list-template 'timeclock-day-required))
(defun timeclock-day-list-length (day-list)
+ "Return actual length of DAY-LIST, in seconds."
(timeclock-day-list-template 'timeclock-day-length))
(defun timeclock-day-list-debt (day-list)
+ "Return total debt (required - actual) of DAY-LIST."
(timeclock-day-list-template 'timeclock-day-debt))
(defsubst timeclock-day-list-begin (day-list)
+ "Return the start time of DAY-LIST."
(timeclock-day-begin (car day-list)))
(defsubst timeclock-day-list-end (day-list)
+ "Return the end time of DAY-LIST."
(timeclock-day-end (car (last day-list))))
(defun timeclock-day-list-span (day-list)
+ "Return the span of DAY-LIST."
(timeclock-day-list-template 'timeclock-day-span))
(defun timeclock-day-list-break (day-list)
+ "Return the total break of DAY-LIST."
(timeclock-day-list-template 'timeclock-day-break))
(defun timeclock-day-list-projects (day-list)
+ "Return a list of all the projects in DAY-LIST."
(let (projects)
- (while day-list
- (let ((projs (timeclock-day-projects (car day-list))))
- (while projs
- (if projects
- (add-to-list 'projects (car projs))
- (setq projects (list (car projs))))
- (setq projs (cdr projs))))
- (setq day-list (cdr day-list)))
+ (dolist (day day-list)
+ (dolist (proj (timeclock-day-projects day))
+ (if projects
+ (add-to-list 'projects proj)
+ (setq projects (list proj)))))
projects))
-
(defsubst timeclock-current-debt (&optional log-data)
+ "Return the seconds debt from LOG-DATA, default `timeclock-log-data'."
(nth 0 (or log-data (timeclock-log-data))))
(defsubst timeclock-day-alist (&optional log-data)
+ "Return the date alist from LOG-DATA, default `timeclock-log-data'."
(nth 1 (or log-data (timeclock-log-data))))
(defun timeclock-day-list (&optional log-data)
- (let ((alist (timeclock-day-alist log-data))
- day-list)
- (while alist
- (setq day-list (cons (cdar alist) day-list)
- alist (cdr alist)))
+ "Return a list of the cdrs of the date alist from LOG-DATA."
+ (let (day-list)
+ (dolist (date-list (timeclock-day-alist log-data))
+ (setq day-list (cons (cdr date-list) day-list)))
day-list))
(defsubst timeclock-project-alist (&optional log-data)
+ "Return the project alist from LOG-DATA, default `timeclock-log-data'."
(nth 2 (or log-data (timeclock-log-data))))
-
(defun timeclock-log-data (&optional recent-only filename)
"Return the contents of the timelog file, in a useful format.
If the optional argument RECENT-ONLY is non-nil, only show the contents
(if (null proj)
(setcar (cddr log-data)
(cons (cons desc (list entry))
- (car (cddr log-data))))
+ (nth 2 log-data)))
(nconc (cdr proj) (list entry)))))))
(forward-line))
(if day
(setcar (nthcdr 2 decoded) 0)
(apply 'encode-time decoded)))
-(defun timeclock-geometric-mean (l)
- "Compute the geometric mean of the values in the list L."
+(defun timeclock-mean (l)
+ "Compute the arithmetic mean of the values in the list L."
(let ((total 0)
(count 0))
- (while l
- (setq total (+ total (car l))
- count (1+ count)
- l (cdr l)))
- (if (> count 0)
- (/ total count)
- 0)))
+ (dolist (thisl l)
+ (setq total (+ total thisl)
+ count (1+ count)))
+ (if (zerop count)
+ 0
+ (/ total count))))
(defun timeclock-generate-report (&optional html-p)
"Generate a summary report based on the current timelog file.
By default, the report is in plain text, but if the optional argument
HTML-P is non-nil, HTML markup is added."
- (interactive)
+ (interactive "P")
(let ((log (timeclock-log-data))
(today (timeclock-day-base)))
(if html-p (insert "<p>"))
done)
(if (timeclock-currently-in-p)
(insert "IN")
- (if (or (null project) (= (length project) 0))
+ (if (zerop (length project))
(progn (insert "Done Working Today")
(setq done t))
(insert "OUT")))
(lengths (vector '(0 0) thirty-days-ago three-months-ago
six-months-ago one-year-ago)))
;; collect statistics from complete timelog
- (while day-list
+ (dolist (day day-list)
(let ((i 0) (l 5))
(while (< i l)
(unless (time-less-p
- (timeclock-day-begin (car day-list))
+ (timeclock-day-begin day)
(aref lengths i))
(let ((base (timeclock-time-to-seconds
(timeclock-day-base
- (timeclock-day-begin (car day-list))))))
+ (timeclock-day-begin day)))))
(nconc (aref time-in i)
(list (- (timeclock-time-to-seconds
- (timeclock-day-begin (car day-list)))
+ (timeclock-day-begin day))
base)))
- (let ((span (timeclock-day-span (car day-list)))
- (len (timeclock-day-length (car day-list)))
- (req (timeclock-day-required (car day-list))))
+ (let ((span (timeclock-day-span day))
+ (len (timeclock-day-length day))
+ (req (timeclock-day-required day)))
;; If the day's actual work length is less than
;; 70% of its span, then likely the exit time
;; and break amount are not worthwhile adding to
(> (/ (float len) (float span)) 0.70))
(nconc (aref time-out i)
(list (- (timeclock-time-to-seconds
- (timeclock-day-end (car day-list)))
+ (timeclock-day-end day))
base)))
(nconc (aref breaks i) (list (- span len))))
(if req
(setq len (+ len (- timeclock-workday req))))
(nconc (aref workday i) (list len)))))
- (setq i (1+ i))))
- (setq day-list (cdr day-list)))
+ (setq i (1+ i)))))
;; average statistics
(let ((i 0) (l 5))
(while (< i l)
- (aset time-in i (timeclock-geometric-mean
- (cdr (aref time-in i))))
- (aset time-out i (timeclock-geometric-mean
- (cdr (aref time-out i))))
- (aset breaks i (timeclock-geometric-mean
- (cdr (aref breaks i))))
- (aset workday i (timeclock-geometric-mean
- (cdr (aref workday i))))
+ (aset time-in i (timeclock-mean (cdr (aref time-in i))))
+ (aset time-out i (timeclock-mean (cdr (aref time-out i))))
+ (aset breaks i (timeclock-mean (cdr (aref breaks i))))
+ (aset workday i (timeclock-mean (cdr (aref workday i))))
(setq i (1+ i))))
;; Output the HTML table
(insert "<tr>\n")
(if (file-readable-p timeclock-file)
(timeclock-reread-log))
-;;; arch-tag: a0be3377-deb6-44ec-b9a2-a7be28436a40
+;; arch-tag: a0be3377-deb6-44ec-b9a2-a7be28436a40
;;; timeclock.el ends here