Pārlūkot izejas kodu

org-table: new defcustom `org-table-duration-custom-format'.

This allows to display the output of duration computations
as a fraction of days, hours, minutes or seconds.

Thanks to Daniel E. Doherty for bringing up this need.

* org-table.el (org-table-duration-custom-format): New
defcustom to select output format of durations computations.
(org-table-time-seconds-to-string): Use the new variable.
(org-table-eval-formula): Allow `t' as a flag, on top of `T'.
`t' will use the custom output format defined in
`org-table-duration-custom-format.
Bastien Guerry 13 gadi atpakaļ
vecāks
revīzija
70fab165e1
2 mainītis faili ar 51 papildinājumiem un 12 dzēšanām
  1. 16 7
      doc/org.texi
  2. 35 5
      lisp/org-table.el

+ 16 - 7
doc/org.texi

@@ -2497,7 +2497,6 @@ n3 s3 e2 f4   @r{Normal, scientific, engineering, or fixed}
 D R           @r{angle modes: degrees, radians}
 D R           @r{angle modes: degrees, radians}
 F S           @r{fraction and symbolic modes}
 F S           @r{fraction and symbolic modes}
 N             @r{interpret all fields as numbers, use 0 for non-numbers}
 N             @r{interpret all fields as numbers, use 0 for non-numbers}
-T             @r{force text interpretation}
 E             @r{keep empty fields in ranges}
 E             @r{keep empty fields in ranges}
 L             @r{literal}
 L             @r{literal}
 @end example
 @end example
@@ -2534,6 +2533,9 @@ Calc also contains a complete set of logical operations.  For example
 if($1<20,teen,string(""))  @r{"teen" if age $1 less than 20, else empty}
 if($1<20,teen,string(""))  @r{"teen" if age $1 less than 20, else empty}
 @end example
 @end example
 
 
+Note that you can also use two org-specific flags @code{T} and @code{t} for
+durations computations @ref{Durations and time values}.
+
 @node Formula syntax for Lisp, Durations and time values, Formula syntax for Calc, The spreadsheet
 @node Formula syntax for Lisp, Durations and time values, Formula syntax for Calc, The spreadsheet
 @subsection Emacs Lisp forms as formulas
 @subsection Emacs Lisp forms as formulas
 @cindex Lisp forms, as table formulas
 @cindex Lisp forms, as table formulas
@@ -2569,6 +2571,7 @@ embed them in list or vector syntax.  Here are a few examples---note how the
 @subsection Durations and time values
 @subsection Durations and time values
 @cindex Duration, computing
 @cindex Duration, computing
 @cindex Time, computing
 @cindex Time, computing
+@vindex org-table-duration-custom-format
 
 
 If you want to compute time values use the @code{T} flag, either in Calc
 If you want to compute time values use the @code{T} flag, either in Calc
 formulas or Elisp formulas:
 formulas or Elisp formulas:
@@ -2578,15 +2581,21 @@ formulas or Elisp formulas:
   |  Task 1 |   Task 2 |    Total |
   |  Task 1 |   Task 2 |    Total |
   |---------+----------+----------|
   |---------+----------+----------|
   |    2:12 |     1:47 | 03:59:00 |
   |    2:12 |     1:47 | 03:59:00 |
-  | 3:02:20 | -2:07:00 | 00:55:20 |
-  #+TBLFM: $3=$1+$2;T
+  | 3:02:20 | -2:07:00 |     0.92 |
+  #+TBLFM: @@2$3=$1+$2;T::@@3$3=$1+$2;t
 @end group
 @end group
 @end example
 @end example
 
 
-Duration values are of the form @code{[HH:MM[:SS]}, where seconds are
-optional.  The computed duration will be displayed as @code{[HH:MM:SS}.
-Negative values can be manipulated as well, and integers are considered
-as seconds in addition and subtraction.
+Input duration values must be of the form @code{[HH:MM[:SS]}, where seconds
+are optional.  With the @code{T} flag, computed durations will be displayed
+as @code{[HH:MM:SS} (see the first formula above).  With the @code{t} flag,
+computed durations will be displayed according to the value of the variable
+@code{org-table-duration-custom-format}, which defaults to @code{'hours} and
+will display the result as a fraction of hours (see the second formula in the
+example above).
+
+Negative duration values can be manipulated as well, and integers will be
+considered as seconds in addition and subtraction.
 
 
 @node Field and range formulas, Column formulas, Durations and time values, The spreadsheet
 @node Field and range formulas, Column formulas, Durations and time values, The spreadsheet
 @subsection Field and range formulas
 @subsection Field and range formulas

+ 35 - 5
lisp/org-table.el

@@ -231,6 +231,18 @@ relies on the variables to be present in the list."
   :group 'org-table-calculation
   :group 'org-table-calculation
   :type 'plist)
   :type 'plist)
 
 
+(defcustom org-table-duration-custom-format 'hours
+  "Format for the output of calc computations like $1+$2;t.
+The default value is 'hours, and will output the results as a
+number of hours.  Other allowed values are 'seconds, 'minutes and
+'days, and the output will be a fraction of seconds, minutes or
+days."
+  :group 'org-table-calculation
+  :type '(choice (symbol :tag "Seconds" 'seconds)
+		 (symbol :tag "Minutes" 'minutes)
+		 (symbol :tag "Hours  " 'hours)
+		 (symbol :tag "Days   " 'days)))
+
 (defcustom org-table-formula-evaluate-inline t
 (defcustom org-table-formula-evaluate-inline t
   "Non-nil means TAB and RET evaluate a formula in current table field.
   "Non-nil means TAB and RET evaluate a formula in current table field.
 If the current field starts with an equal sign, it is assumed to be a formula
 If the current field starts with an equal sign, it is assumed to be a formula
@@ -2412,6 +2424,12 @@ not overwrite the stored one."
 	      (setq fmt (replace-match "" t t fmt)))
 	      (setq fmt (replace-match "" t t fmt)))
 	    (if (string-match "T" fmt)
 	    (if (string-match "T" fmt)
 		(setq duration t numbers t
 		(setq duration t numbers t
+		      duration-output-format nil
+		      fmt (replace-match "" t t fmt)))
+	    (if (string-match "t" fmt)
+		(setq duration t 
+		      duration-output-format org-table-duration-custom-format
+		      numbers t
 		      fmt (replace-match "" t t fmt)))
 		      fmt (replace-match "" t t fmt)))
 	    (if (string-match "N" fmt)
 	    (if (string-match "N" fmt)
 		(setq numbers t
 		(setq numbers t
@@ -2523,12 +2541,14 @@ not overwrite the stored one."
 		       (error "#ERROR"))
 		       (error "#ERROR"))
 		  ev (if (numberp ev) (number-to-string ev) ev)
 		  ev (if (numberp ev) (number-to-string ev) ev)
 		  ev (if duration (org-table-time-seconds-to-string
 		  ev (if duration (org-table-time-seconds-to-string
-				   (string-to-number ev)) ev))
+				   (string-to-number ev)
+				   duration-output-format) ev))
 	  (or (fboundp 'calc-eval)
 	  (or (fboundp 'calc-eval)
 	      (error "Calc does not seem to be installed, and is needed to evaluate the formula"))
 	      (error "Calc does not seem to be installed, and is needed to evaluate the formula"))
 	  (setq ev (calc-eval (cons form modes) (if numbers 'num))
 	  (setq ev (calc-eval (cons form modes) (if numbers 'num))
 		ev (if duration (org-table-time-seconds-to-string
 		ev (if duration (org-table-time-seconds-to-string
-				 (string-to-number ev)) ev)))
+				 (string-to-number ev)
+				 duration-output-format) ev)))
 
 
 	(when org-table-formula-debug
 	(when org-table-formula-debug
 	  (with-output-to-temp-buffer "*Substitution History*"
 	  (with-output-to-temp-buffer "*Substitution History*"
@@ -3237,9 +3257,19 @@ If S is a string representing a number, keep this number."
      (t (setq res (string-to-number s))))
      (t (setq res (string-to-number s))))
     (number-to-string res)))
     (number-to-string res)))
 
 
-(defun org-table-time-seconds-to-string (secs)
-  "Convert a number of seconds to a time string."
-  (org-format-seconds "%.2h:%.2m:%.2s" secs))
+(defun org-table-time-seconds-to-string (secs &optional output-format)
+  "Convert a number of seconds to a time string.
+If OUTPUT-FORMAT is non-nil, return a number of days, hours,
+minutes or seconds."
+  (cond ((eq output-format 'days)
+	 (format "%.3f" (/ (float secs) 86400)))
+	((eq output-format 'hours)
+	 (format "%.2f" (/ (float secs) 3600)))
+	((eq output-format 'minutes)
+	 (format "%.1f" (/ (float secs) 60)))
+	((eq output-format 'seconds)
+	 (format "%d" secs))
+	(t (org-format-seconds "%.2h:%.2m:%.2s" secs))))
 
 
 (defun org-table-fedit-convert-buffer (function)
 (defun org-table-fedit-convert-buffer (function)
   "Convert all references in this buffer, using FUNCTION."
   "Convert all references in this buffer, using FUNCTION."