diff options
| author | John Wiegley | 2001-03-16 21:39:31 +0000 |
|---|---|---|
| committer | John Wiegley | 2001-03-16 21:39:31 +0000 |
| commit | 9329ea14c5864787bf425da59d3a503b72a8dea5 (patch) | |
| tree | a8c0b45207186bd8a3ac2c317edb2c6dc3cd2729 /lisp | |
| parent | dbee590bf68749c303ec2952b9dd7d811e9416ec (diff) | |
| download | emacs-9329ea14c5864787bf425da59d3a503b72a8dea5.tar.gz emacs-9329ea14c5864787bf425da59d3a503b72a8dea5.zip | |
see ChangeLog
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/calendar/timeclock.el | 409 |
1 files changed, 318 insertions, 91 deletions
diff --git a/lisp/calendar/timeclock.el b/lisp/calendar/timeclock.el index 773c131a24f..550214c6c29 100644 --- a/lisp/calendar/timeclock.el +++ b/lisp/calendar/timeclock.el | |||
| @@ -431,7 +431,7 @@ Returns the new value of `timeclock-discrepancy'." | |||
| 431 | (interactive) | 431 | (interactive) |
| 432 | (setq timeclock-discrepancy nil) | 432 | (setq timeclock-discrepancy nil) |
| 433 | (timeclock-find-discrep) | 433 | (timeclock-find-discrep) |
| 434 | (if timeclock-modeline-display | 434 | (if (and timeclock-discrepancy timeclock-modeline-display) |
| 435 | (timeclock-update-modeline)) | 435 | (timeclock-update-modeline)) |
| 436 | timeclock-discrepancy) | 436 | timeclock-discrepancy) |
| 437 | 437 | ||
| @@ -913,7 +913,7 @@ See the documentation for the given function if more info is needed." | |||
| 913 | (now (current-time)) | 913 | (now (current-time)) |
| 914 | (todays-date (timeclock-time-to-date now)) | 914 | (todays-date (timeclock-time-to-date now)) |
| 915 | last-date-limited last-date-seconds last-date | 915 | last-date-limited last-date-seconds last-date |
| 916 | (line 0) last beg day entry) | 916 | (line 0) last beg day entry event) |
| 917 | (with-temp-buffer | 917 | (with-temp-buffer |
| 918 | (insert-file-contents (or filename timeclock-file)) | 918 | (insert-file-contents (or filename timeclock-file)) |
| 919 | (when recent-only | 919 | (when recent-only |
| @@ -940,11 +940,15 @@ See the documentation for the given function if more info is needed." | |||
| 940 | (let ((date (timeclock-time-to-date (cadr event)))) | 940 | (let ((date (timeclock-time-to-date (cadr event)))) |
| 941 | (if (and last-date | 941 | (if (and last-date |
| 942 | (not (equal date last-date))) | 942 | (not (equal date last-date))) |
| 943 | (setcar (cdr log-data) | 943 | (progn |
| 944 | (cons (cons last-date day) | 944 | (setcar (cdr log-data) |
| 945 | (cadr log-data))) | 945 | (cons (cons last-date day) |
| 946 | (setq day (list (and last-date-limited | 946 | (cadr log-data))) |
| 947 | last-date-seconds)))) | 947 | (setq day (list (and last-date-limited |
| 948 | last-date-seconds)))) | ||
| 949 | (unless day | ||
| 950 | (setq day (list (and last-date-limited | ||
| 951 | last-date-seconds))))) | ||
| 948 | (setq last-date date | 952 | (setq last-date date |
| 949 | last-date-limited nil))) | 953 | last-date-limited nil))) |
| 950 | ((equal (downcase (car event)) "o") | 954 | ((equal (downcase (car event)) "o") |
| @@ -963,7 +967,7 @@ See the documentation for the given function if more info is needed." | |||
| 963 | (nconc day (list entry)) | 967 | (nconc day (list entry)) |
| 964 | (setq desc (nth 2 entry)) | 968 | (setq desc (nth 2 entry)) |
| 965 | (let ((proj (assoc desc (nth 2 log-data)))) | 969 | (let ((proj (assoc desc (nth 2 log-data)))) |
| 966 | (if (not proj) | 970 | (if (null proj) |
| 967 | (setcar (cddr log-data) | 971 | (setcar (cddr log-data) |
| 968 | (cons (cons desc (list entry)) | 972 | (cons (cons desc (list entry)) |
| 969 | (car (cddr log-data)))) | 973 | (car (cddr log-data)))) |
| @@ -983,90 +987,313 @@ identical to what would be return if `timeclock-relative' were nil." | |||
| 983 | ;; This is not implemented in terms of the functions above, because | 987 | ;; This is not implemented in terms of the functions above, because |
| 984 | ;; it's a bit wasteful to read all of that data in, just to throw | 988 | ;; it's a bit wasteful to read all of that data in, just to throw |
| 985 | ;; away more than 90% of the information afterwards. | 989 | ;; away more than 90% of the information afterwards. |
| 986 | (let* ((now (current-time)) | 990 | (when (file-readable-p timeclock-file) |
| 987 | (todays-date (timeclock-time-to-date now)) | 991 | (let* ((now (current-time)) |
| 988 | (first t) (accum 0) | 992 | (todays-date (timeclock-time-to-date now)) |
| 989 | event beg last-date avg | 993 | (first t) (accum 0) |
| 990 | last-date-limited last-date-seconds) | 994 | event beg last-date avg |
| 991 | (unless timeclock-discrepancy | 995 | last-date-limited last-date-seconds) |
| 992 | (setq timeclock-project-list nil | 996 | (unless timeclock-discrepancy |
| 993 | timeclock-last-project nil | 997 | (setq timeclock-project-list nil |
| 994 | timeclock-reason-list nil | 998 | timeclock-last-project nil |
| 995 | timeclock-elapsed 0) | 999 | timeclock-reason-list nil |
| 996 | (with-temp-buffer | 1000 | timeclock-elapsed 0) |
| 997 | (insert-file-contents timeclock-file) | 1001 | (with-temp-buffer |
| 998 | (goto-char (point-max)) | 1002 | (insert-file-contents timeclock-file) |
| 999 | (unless (re-search-backward "^b\\s-+" nil t) | 1003 | (goto-char (point-max)) |
| 1000 | (goto-char (point-min))) | 1004 | (unless (re-search-backward "^b\\s-+" nil t) |
| 1001 | (while (setq event (timeclock-read-moment)) | 1005 | (goto-char (point-min))) |
| 1002 | (cond ((equal (car event) "b") | 1006 | (while (setq event (timeclock-read-moment)) |
| 1003 | (setq accum (string-to-number (nth 2 event)))) | 1007 | (cond ((equal (car event) "b") |
| 1004 | ((equal (car event) "h") | 1008 | (setq accum (string-to-number (nth 2 event)))) |
| 1005 | (setq last-date-limited | 1009 | ((equal (car event) "h") |
| 1006 | (timeclock-time-to-date (cadr event)) | 1010 | (setq last-date-limited |
| 1007 | last-date-seconds | 1011 | (timeclock-time-to-date (cadr event)) |
| 1008 | (* (string-to-number (nth 2 event)) 3600.0))) | 1012 | last-date-seconds |
| 1009 | ((equal (car event) "i") | 1013 | (* (string-to-number (nth 2 event)) 3600.0))) |
| 1010 | (when (and (nth 2 event) | 1014 | ((equal (car event) "i") |
| 1011 | (> (length (nth 2 event)) 0)) | 1015 | (when (and (nth 2 event) |
| 1012 | (add-to-list 'timeclock-project-list (nth 2 event)) | 1016 | (> (length (nth 2 event)) 0)) |
| 1013 | (setq timeclock-last-project (nth 2 event))) | 1017 | (add-to-list 'timeclock-project-list (nth 2 event)) |
| 1014 | (let ((date (timeclock-time-to-date (cadr event)))) | 1018 | (setq timeclock-last-project (nth 2 event))) |
| 1015 | (if (and timeclock-relative | 1019 | (let ((date (timeclock-time-to-date (cadr event)))) |
| 1016 | (if last-date | 1020 | (if (and timeclock-relative |
| 1017 | (not (equal date last-date)) | 1021 | (if last-date |
| 1018 | first)) | 1022 | (not (equal date last-date)) |
| 1019 | (setq first nil | 1023 | first)) |
| 1020 | accum (- accum | 1024 | (setq first nil |
| 1021 | (if last-date-limited | 1025 | accum (- accum |
| 1022 | last-date-seconds | 1026 | (if last-date-limited |
| 1023 | timeclock-workday)))) | 1027 | last-date-seconds |
| 1024 | (setq last-date date | 1028 | timeclock-workday)))) |
| 1025 | last-date-limited nil) | 1029 | (setq last-date date |
| 1026 | (if beg | 1030 | last-date-limited nil) |
| 1027 | (error "Error in format of timelog file!") | 1031 | (if beg |
| 1028 | (setq beg (timeclock-time-to-seconds (cadr event)))))) | ||
| 1029 | ((equal (downcase (car event)) "o") | ||
| 1030 | (if (and (nth 2 event) | ||
| 1031 | (> (length (nth 2 event)) 0)) | ||
| 1032 | (add-to-list 'timeclock-reason-list (nth 2 event))) | ||
| 1033 | (if (or timeclock-relative | ||
| 1034 | (equal last-date todays-date)) | ||
| 1035 | (if (not beg) | ||
| 1036 | (error "Error in format of timelog file!") | 1032 | (error "Error in format of timelog file!") |
| 1037 | (setq timeclock-last-period | 1033 | (setq beg (timeclock-time-to-seconds (cadr event)))))) |
| 1038 | (- (timeclock-time-to-seconds (cadr event)) beg) | 1034 | ((equal (downcase (car event)) "o") |
| 1039 | accum (+ timeclock-last-period accum) | 1035 | (if (and (nth 2 event) |
| 1040 | beg nil))) | 1036 | (> (length (nth 2 event)) 0)) |
| 1041 | (if (equal last-date todays-date) | 1037 | (add-to-list 'timeclock-reason-list (nth 2 event))) |
| 1042 | (setq timeclock-elapsed | 1038 | (if (or timeclock-relative |
| 1043 | (+ timeclock-last-period timeclock-elapsed))))) | 1039 | (equal last-date todays-date)) |
| 1044 | (setq timeclock-last-event event | 1040 | (if (not beg) |
| 1045 | timeclock-last-event-workday | 1041 | (error "Error in format of timelog file!") |
| 1046 | (if (equal (timeclock-time-to-date now) | 1042 | (setq timeclock-last-period |
| 1047 | last-date-limited) | 1043 | (- (timeclock-time-to-seconds (cadr event)) |
| 1048 | last-date-seconds | 1044 | beg) |
| 1049 | timeclock-workday)) | 1045 | accum (+ timeclock-last-period accum) |
| 1050 | (forward-line)) | 1046 | beg nil))) |
| 1051 | (setq timeclock-discrepancy accum))) | 1047 | (if (equal last-date todays-date) |
| 1052 | (setq accum (if today-only | 1048 | (setq timeclock-elapsed |
| 1053 | timeclock-elapsed | 1049 | (+ timeclock-last-period timeclock-elapsed))))) |
| 1054 | timeclock-discrepancy)) | 1050 | (setq timeclock-last-event event |
| 1055 | (if timeclock-last-event | 1051 | timeclock-last-event-workday |
| 1056 | (if (equal (car timeclock-last-event) "i") | 1052 | (if (equal (timeclock-time-to-date now) |
| 1057 | (setq accum (+ accum (timeclock-last-period now))) | 1053 | last-date-limited) |
| 1058 | (if (not (equal (timeclock-time-to-date | 1054 | last-date-seconds |
| 1059 | (cadr timeclock-last-event)) | 1055 | timeclock-workday)) |
| 1060 | (timeclock-time-to-date now))) | 1056 | (forward-line)) |
| 1061 | (setq accum (- accum timeclock-last-event-workday))))) | 1057 | (setq timeclock-discrepancy accum))) |
| 1062 | (setq accum | 1058 | (setq accum (if today-only |
| 1063 | (- accum | 1059 | timeclock-elapsed |
| 1064 | (if (and timeclock-last-event | 1060 | timeclock-discrepancy)) |
| 1065 | (equal (timeclock-time-to-date | 1061 | (if timeclock-last-event |
| 1066 | (cadr timeclock-last-event)) | 1062 | (if (equal (car timeclock-last-event) "i") |
| 1067 | (timeclock-time-to-date now))) | 1063 | (setq accum (+ accum (timeclock-last-period now))) |
| 1068 | timeclock-last-event-workday | 1064 | (if (not (equal (timeclock-time-to-date |
| 1069 | timeclock-workday))))) | 1065 | (cadr timeclock-last-event)) |
| 1066 | (timeclock-time-to-date now))) | ||
| 1067 | (setq accum (- accum timeclock-last-event-workday))))) | ||
| 1068 | (setq accum | ||
| 1069 | (- accum | ||
| 1070 | (if (and timeclock-last-event | ||
| 1071 | (equal (timeclock-time-to-date | ||
| 1072 | (cadr timeclock-last-event)) | ||
| 1073 | (timeclock-time-to-date now))) | ||
| 1074 | timeclock-last-event-workday | ||
| 1075 | timeclock-workday)))))) | ||
| 1076 | |||
| 1077 | ;;; A reporting function that uses timeclock-log-data | ||
| 1078 | |||
| 1079 | (defun timeclock-time-less-p (t1 t2) | ||
| 1080 | "Say whether time T1 is less than time T2." | ||
| 1081 | (or (< (car t1) (car t2)) | ||
| 1082 | (and (= (car t1) (car t2)) | ||
| 1083 | (< (nth 1 t1) (nth 1 t2))))) | ||
| 1084 | |||
| 1085 | (defun timeclock-day-base (&optional time) | ||
| 1086 | "Given a time within a day, return 0:0:0 within that day." | ||
| 1087 | (let ((decoded (decode-time (or time (current-time))))) | ||
| 1088 | (setcar (nthcdr 0 decoded) 0) | ||
| 1089 | (setcar (nthcdr 1 decoded) 0) | ||
| 1090 | (setcar (nthcdr 2 decoded) 0) | ||
| 1091 | (apply 'encode-time decoded))) | ||
| 1092 | |||
| 1093 | (defun timeclock-geometric-mean (l) | ||
| 1094 | "Compute the geometric mean of the list L." | ||
| 1095 | (let ((total 0) | ||
| 1096 | (count 0)) | ||
| 1097 | (while l | ||
| 1098 | (setq total (+ total (car l)) | ||
| 1099 | count (1+ count) | ||
| 1100 | l (cdr l))) | ||
| 1101 | (if (> count 0) | ||
| 1102 | (/ total count) | ||
| 1103 | 0))) | ||
| 1104 | |||
| 1105 | (defun timeclock-generate-report (&optional html-p) | ||
| 1106 | "Generate a summary report based on the current timelog file." | ||
| 1107 | (interactive) | ||
| 1108 | (let ((log (timeclock-log-data)) | ||
| 1109 | (today (timeclock-day-base))) | ||
| 1110 | (if html-p (insert "<p>")) | ||
| 1111 | (insert "Currently ") | ||
| 1112 | (let ((project (nth 2 timeclock-last-event)) | ||
| 1113 | (begin (nth 1 timeclock-last-event)) | ||
| 1114 | done) | ||
| 1115 | (if (timeclock-currently-in-p) | ||
| 1116 | (insert "IN") | ||
| 1117 | (if (or (null project) (= (length project) 0)) | ||
| 1118 | (progn (insert "Done Working Today") | ||
| 1119 | (setq done t)) | ||
| 1120 | (insert "OUT"))) | ||
| 1121 | (unless done | ||
| 1122 | (insert " since " (format-time-string "%Y/%m/%d %-I:%M %p" begin)) | ||
| 1123 | (if html-p | ||
| 1124 | (insert "<br>\n<b>") | ||
| 1125 | (insert "\n*")) | ||
| 1126 | (if (timeclock-currently-in-p) | ||
| 1127 | (insert "Working on ")) | ||
| 1128 | (if html-p | ||
| 1129 | (insert "</b><br>\n") | ||
| 1130 | (insert project "*\n")) | ||
| 1131 | (let ((proj-data (cdr (assoc project (timeclock-project-alist log)))) | ||
| 1132 | (two-weeks-ago (timeclock-seconds-to-time | ||
| 1133 | (- (timeclock-time-to-seconds today) | ||
| 1134 | (* 2 7 24 60 60)))) | ||
| 1135 | two-week-len today-len) | ||
| 1136 | (while proj-data | ||
| 1137 | (if (not (timeclock-time-less-p | ||
| 1138 | (timeclock-entry-begin (car proj-data)) today)) | ||
| 1139 | (setq today-len (timeclock-entry-list-length proj-data) | ||
| 1140 | proj-data nil) | ||
| 1141 | (if (and (null two-week-len) | ||
| 1142 | (not (timeclock-time-less-p | ||
| 1143 | (timeclock-entry-begin (car proj-data)) | ||
| 1144 | two-weeks-ago))) | ||
| 1145 | (setq two-week-len (timeclock-entry-list-length proj-data))) | ||
| 1146 | (setq proj-data (cdr proj-data)))) | ||
| 1147 | (if (null two-week-len) | ||
| 1148 | (setq two-week-len today-len)) | ||
| 1149 | (if html-p (insert "<p>")) | ||
| 1150 | (insert "\nTime spent on this task today: " | ||
| 1151 | (timeclock-seconds-to-string today-len) | ||
| 1152 | ". In the last two weeks: " | ||
| 1153 | (timeclock-seconds-to-string two-week-len)) | ||
| 1154 | (if html-p (insert "<br>")) | ||
| 1155 | (insert "\n" | ||
| 1156 | (timeclock-seconds-to-string (timeclock-workday-elapsed)) | ||
| 1157 | " worked today, " | ||
| 1158 | (timeclock-seconds-to-string (timeclock-workday-remaining)) | ||
| 1159 | " remaining, done at " | ||
| 1160 | (timeclock-when-to-leave-string) "\n"))) | ||
| 1161 | (if html-p (insert "<p>")) | ||
| 1162 | (insert "\nThere have been " | ||
| 1163 | (number-to-string | ||
| 1164 | (length (timeclock-day-alist log))) | ||
| 1165 | " days of activity, starting " | ||
| 1166 | (caar (last (timeclock-day-alist log)))) | ||
| 1167 | (if html-p (insert "</p>")) | ||
| 1168 | (when html-p | ||
| 1169 | (insert "<p> | ||
| 1170 | <table> | ||
| 1171 | <td width=\"25\"><br></td><td> | ||
| 1172 | <table border=1 cellpadding=3> | ||
| 1173 | <tr><th><i>Statistics</i></th> | ||
| 1174 | <th>Entire</th> | ||
| 1175 | <th>-30 days</th> | ||
| 1176 | <th>-3 mons</th> | ||
| 1177 | <th>-6 mons</th> | ||
| 1178 | <th>-1 year</th> | ||
| 1179 | </tr>") | ||
| 1180 | (let* ((day-list (timeclock-day-list)) | ||
| 1181 | (thirty-days-ago (timeclock-seconds-to-time | ||
| 1182 | (- (timeclock-time-to-seconds today) | ||
| 1183 | (* 30 24 60 60)))) | ||
| 1184 | (three-months-ago (timeclock-seconds-to-time | ||
| 1185 | (- (timeclock-time-to-seconds today) | ||
| 1186 | (* 90 24 60 60)))) | ||
| 1187 | (six-months-ago (timeclock-seconds-to-time | ||
| 1188 | (- (timeclock-time-to-seconds today) | ||
| 1189 | (* 180 24 60 60)))) | ||
| 1190 | (one-year-ago (timeclock-seconds-to-time | ||
| 1191 | (- (timeclock-time-to-seconds today) | ||
| 1192 | (* 365 24 60 60)))) | ||
| 1193 | (time-in (vector (list t) (list t) (list t) (list t) (list t))) | ||
| 1194 | (time-out (vector (list t) (list t) (list t) (list t) (list t))) | ||
| 1195 | (breaks (vector (list t) (list t) (list t) (list t) (list t))) | ||
| 1196 | (workday (vector (list t) (list t) (list t) (list t) (list t))) | ||
| 1197 | (lengths (vector '(0 0) thirty-days-ago three-months-ago | ||
| 1198 | six-months-ago one-year-ago))) | ||
| 1199 | ;; collect statistics from complete timelog | ||
| 1200 | (while day-list | ||
| 1201 | (let ((i 0) (l 5)) | ||
| 1202 | (while (< i l) | ||
| 1203 | (unless (timeclock-time-less-p | ||
| 1204 | (timeclock-day-begin (car day-list)) | ||
| 1205 | (aref lengths i)) | ||
| 1206 | (let ((base (timeclock-time-to-seconds | ||
| 1207 | (timeclock-day-base | ||
| 1208 | (timeclock-day-begin (car day-list)))))) | ||
| 1209 | (nconc (aref time-in i) | ||
| 1210 | (list (- (timeclock-time-to-seconds | ||
| 1211 | (timeclock-day-begin (car day-list))) | ||
| 1212 | base))) | ||
| 1213 | (let ((span (timeclock-day-span (car day-list))) | ||
| 1214 | (len (timeclock-day-length (car day-list))) | ||
| 1215 | (req (timeclock-day-required (car day-list)))) | ||
| 1216 | ;; If the day's actual work length is less than | ||
| 1217 | ;; 70% of its span, then likely the exit time | ||
| 1218 | ;; and break amount are not worthwhile adding to | ||
| 1219 | ;; the statistic | ||
| 1220 | (when (and (> span 0) | ||
| 1221 | (> (/ (float len) (float span)) 0.70)) | ||
| 1222 | (nconc (aref time-out i) | ||
| 1223 | (list (- (timeclock-time-to-seconds | ||
| 1224 | (timeclock-day-end (car day-list))) | ||
| 1225 | base))) | ||
| 1226 | (nconc (aref breaks i) (list (- span len)))) | ||
| 1227 | (if req | ||
| 1228 | (setq len (+ len (- timeclock-workday req)))) | ||
| 1229 | (nconc (aref workday i) (list len))))) | ||
| 1230 | (setq i (1+ i)))) | ||
| 1231 | (setq day-list (cdr day-list))) | ||
| 1232 | ;; average statistics | ||
| 1233 | (let ((i 0) (l 5)) | ||
| 1234 | (while (< i l) | ||
| 1235 | (aset time-in i (timeclock-geometric-mean | ||
| 1236 | (cdr (aref time-in i)))) | ||
| 1237 | (aset time-out i (timeclock-geometric-mean | ||
| 1238 | (cdr (aref time-out i)))) | ||
| 1239 | (aset breaks i (timeclock-geometric-mean | ||
| 1240 | (cdr (aref breaks i)))) | ||
| 1241 | (aset workday i (timeclock-geometric-mean | ||
| 1242 | (cdr (aref workday i)))) | ||
| 1243 | (setq i (1+ i)))) | ||
| 1244 | ;; Output the HTML table | ||
| 1245 | (insert "<tr>\n") | ||
| 1246 | (insert "<td align=\"center\">Time in</td>\n") | ||
| 1247 | (let ((i 0) (l 5)) | ||
| 1248 | (while (< i l) | ||
| 1249 | (insert "<td align=\"right\">" | ||
| 1250 | (timeclock-seconds-to-string (aref time-in i)) | ||
| 1251 | "</td>\n") | ||
| 1252 | (setq i (1+ i)))) | ||
| 1253 | (insert "</tr>\n") | ||
| 1254 | |||
| 1255 | (insert "<tr>\n") | ||
| 1256 | (insert "<td align=\"center\">Time out</td>\n") | ||
| 1257 | (let ((i 0) (l 5)) | ||
| 1258 | (while (< i l) | ||
| 1259 | (insert "<td align=\"right\">" | ||
| 1260 | (timeclock-seconds-to-string (aref time-out i)) | ||
| 1261 | "</td>\n") | ||
| 1262 | (setq i (1+ i)))) | ||
| 1263 | (insert "</tr>\n") | ||
| 1264 | |||
| 1265 | (insert "<tr>\n") | ||
| 1266 | (insert "<td align=\"center\">Break</td>\n") | ||
| 1267 | (let ((i 0) (l 5)) | ||
| 1268 | (while (< i l) | ||
| 1269 | (insert "<td align=\"right\">" | ||
| 1270 | (timeclock-seconds-to-string (aref breaks i)) | ||
| 1271 | "</td>\n") | ||
| 1272 | (setq i (1+ i)))) | ||
| 1273 | (insert "</tr>\n") | ||
| 1274 | |||
| 1275 | (insert "<tr>\n") | ||
| 1276 | (insert "<td align=\"center\">Workday</td>\n") | ||
| 1277 | (let ((i 0) (l 5)) | ||
| 1278 | (while (< i l) | ||
| 1279 | (insert "<td align=\"right\">" | ||
| 1280 | (timeclock-seconds-to-string (aref workday i)) | ||
| 1281 | "</td>\n") | ||
| 1282 | (setq i (1+ i)))) | ||
| 1283 | (insert "</tr>\n")) | ||
| 1284 | (insert "<tfoot> | ||
| 1285 | <td colspan=\"6\" align=\"center\"> | ||
| 1286 | <i>These are approximate figures</i></td> | ||
| 1287 | </tfoot> | ||
| 1288 | </table> | ||
| 1289 | </td></table>"))))) | ||
| 1290 | |||
| 1291 | ;;; A helpful little function | ||
| 1292 | |||
| 1293 | (defun timeclock-visit-timelog () | ||
| 1294 | "Open up the .timelog file in another window." | ||
| 1295 | (interactive) | ||
| 1296 | (find-file-other-window timeclock-file)) | ||
| 1070 | 1297 | ||
| 1071 | (provide 'timeclock) | 1298 | (provide 'timeclock) |
| 1072 | 1299 | ||