diff --git a/doc/ChangeLog b/doc/ChangeLog index 225db2937..33adac5dc 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,8 @@ +2008-11-10 Carsten Dominik + + * org.texi (Clocking work time): Document the :formula property of + clock tables. + 2008-11-09 Carsten Dominik * org.texi (Agenda commands): Document the double-prefix version diff --git a/doc/org.texi b/doc/org.texi index 04f14a2f8..f13d3efe8 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -4830,6 +4830,10 @@ new table. The @samp{BEGIN} line can specify options: :step @r{@code{week} or @code{day}, to split the table into chunks.} @r{To use this, @code{:block} or @code{:tstart}, @code{:tend} are needed.} :link @r{Link the item headlines in the table to their origins} +:formula @r{Content of a @code{#+TBLFM} line to be added and evaluated.} + @r{As a special case, @samp{:formula %} adds column with % time.} + @r{If you do not specify a formula here, any existing formula} + @r{below the clock table will survive updates and be evaluated.} @end example So to get a clock summary of the current level 1 tree, for the current day, you could write @@ -4845,6 +4849,11 @@ only to fit it onto the manual.} :tend "<2006-08-10 Thu 12:00>" #+END: clocktable @end example +A summary of the current subtree with % times would be +@example +#+BEGIN: clocktable :scope subtree :link t :formula % +#+END: clocktable +@end example @kindex C-c C-c @item C-c C-c @kindex C-c C-x C-u diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 0819e08dd..84c685b18 100755 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,7 @@ 2008-11-10 Carsten Dominik + * org-clock.el (org-clock-time%): New function. + * org.el (org-entry-get, org-entry-delete): Use safer regexps to retrieve property values. diff --git a/lisp/org-clock.el b/lisp/org-clock.el index 4b59db3cb..ec566d500 100644 --- a/lisp/org-clock.el +++ b/lisp/org-clock.el @@ -819,7 +819,7 @@ the currently selected interval size." (te (plist-get params :tend)) (block (plist-get params :block)) (link (plist-get params :link)) - ipos time p level hlc hdl + ipos time p level hlc hdl content recalc formula pcol cc beg end pos tbl tbl1 range-text rm-file-column scope-is-list) (setq org-clock-file-total-minutes nil) (when step @@ -959,9 +959,37 @@ the currently selected interval size." 'identity (delq nil tbl) (if scope-is-list "\n|-\n" "\n"))) (backward-delete-char 1) + (if (setq formula (plist-get params :formula)) + (cond + ((eq formula '%) + (setq pcol (+ (if scope-is-list 1 0) maxlevel 3)) + (insert + (format + "\n#+TBLFM: $%d='(org-clock-time%% @%d$%d $%d..$%d);%%.1f" + pcol + 2 + (+ 3 (if scope-is-list 1 0)) + (+ (if scope-is-list 1 0) 3) + (1- pcol))) + (setq recalc t)) + ((stringp formula) + (insert "\n#+TBLFM: " formula) + (setq recalc t)) + (t (error "invalid formula in clocktable"))) + ;; Should we rescue an old formula? + (when (stringp (setq content (plist-get params :content))) + (when (string-match "^\\(#\\+TBLFM:.*\\)" content) + (setq recalc t) + (insert "\n" (match-string 1 (plist-get params :content))) + (beginning-of-line 0)))) (goto-char ipos) (skip-chars-forward "^|") (org-table-align) + (when recalc + (if (eq formula '%) + (save-excursion (org-table-goto-column pcol nil 'force) + (insert "%"))) + (org-table-recalculate 'all)) (when rm-file-column (forward-char 1) (org-table-delete-column))))))) @@ -1010,6 +1038,29 @@ the currently selected interval size." lines) "\n")))) +(defun org-clock-time% (total &rest strings) + "Compute a time fraction in percent. +TOTAL s a time string like 10:21 specifying the total times. +STRINGS is a list of strings that should be checked for a time. +The first string that does have a time will be used. +This function is made for clock tables." + (let ((re "\\([0-9]+\\):\\([0-9]+\\)") + tot s) + (save-match-data + (catch 'exit + (if (not (string-match re total)) + (throw 'exit 0.) + (setq tot (+ (string-to-number (match-string 2 total)) + (* 60 (string-to-number (match-string 1 total))))) + (if (= tot 0.) (throw 'exit 0.))) + (while (setq s (pop strings)) + (if (string-match "\\([0-9]+\\):\\([0-9]+\\)" s) + (throw 'exit + (/ (* 100.0 (+ (string-to-number (match-string 2 s)) + (* 60 (string-to-number (match-string 1 s))))) + tot)))) + 0)))) + (defun org-clock-save () "Persist various clock-related data to disk" (with-current-buffer (find-file (expand-file-name org-clock-persist-file))