emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Carsten Dominik <dominik@uva.nl>
To: "news@aleblanc.cotse.net> <news@aleblanc.cotse.net"
	<news@aleblanc.cotse.net>
Cc: emacs-orgmode@gnu.org
Subject: Re: Re: SOLVED: elisp formulas in column view (without converting to tables)
Date: Tue, 9 Jun 2009 08:26:39 +0200	[thread overview]
Message-ID: <3242F661-56E9-4073-9308-762DEB5F25B7@uva.nl> (raw)
In-Reply-To: <87tz5tql66.fsf@it.com>

Hi,

sorry for replying so late to this proposal, which is a very
nice idea.  However, specifying lisp formulas in a #+COLUMNS
definition might be a bit tedious.

In the mean time, we have installed (in version 6.27) a patch by
Mikael Fornius.  This patch defines new operators `min', `max',
and `mean', and special versions for time computations `min:',
`max:', and `mean:'.  The patch also captures all operator
definitions into a single variable, which does allow for
user-defined Lisp operators.

I have not tried, but I believe it might now be simple to add new
operators by just adding to the variable `org-columns-compile-map'.
I would be interested to hear if someone has amended this variable
successfully.  If yes, maybe we can expose it better by making
is a defcustom, or by introducing a buffer-local add-on to it.

Hope this helps

- Carsten

On Mar 16, 2009, at 9:15 PM, <news@aleblanc.cotse.net> <news@aleblanc.cotse.net 
 > wrote:

> <news@aleblanc.cotse.net> writes:
>
>> Hi,
>>   I have rewritten the org-columns-compute function to allow elisp
>>   formulas in column view.
>>   It allows you to specify how to accumulate values from child  
>> headers,
>>   and how to specify the value for the current header, based on other
>>   columns.
>
> Have since discovered that my new version doesn't work with checkbox
> formulas. The solution is to use the old version of org-columns- 
> compute
> if the formula is not an elisp formula. Rename the old function to
> org-columns-compute-orig, and then use this code for
> org-columns-compute:
>
> (defun org-columns-compute (property)
>  "Sum the values of property PROPERTY hierarchically, for the entire  
> buffer."
>  (interactive)
>  (let* ((re (concat "^" outline-regexp))
> 	 (lmax 30) ; Does anyone use deeper levels???
> 	 (level 0)
> 	 (ass (assoc property org-columns-current-fmt-compiled))
> 	 ;; parse elisp form if there is one
> 	 (form (nth 3 ass))
> 	 (uselisp (and (> (length form) 1)
> 		       (or (equal "(" (substring form 0 1))
> 			   (equal "(" (substring form 1 2)))))
> 	 (form (if uselisp
> 		   (replace-regexp-in-string
> 		    "\$\\([^()\" 	]+\\)"
> 		    "(string-to-number (or (org-entry-get nil \"\\1\") \"0\"))"
> 		    (nth 3 ass) t)))
> 	 ;; vector to hold running totals for each level
> 	 (lsum (make-vector lmax (if uselisp nil 0)))
> 	 (format (nth 4 ass))
> 	 (printf (nth 5 ass))
> 	 (beg org-columns-top-level-marker)
> 	 last-level val valflag end sumpos sum-alist str str1 useval  
> prevtotal curtotal newvals)
>    (if uselisp
> 	(save-excursion
> 	  ;; Find the region to compute
> 	  (goto-char beg)
> 	  (setq end (condition-case nil (org-end-of-subtree t) (error  
> (point-max))))
> 	  (goto-char end)
> 	  ;; Walk the tree from the back and do the computations
> 	  (while (re-search-backward re beg t)
> 	    (setq sumpos (match-beginning 0)
> 		  last-level level
> 		  level (org-outline-level)
> 		  ;; total from children, or nil if there were none
> 		  prevtotal (if (< level last-level) (aref lsum last-level) nil)
> 		  ;; total at this level
> 		  curtotal (aref lsum level)
> 		  ;; current property value as string
> 		  val (org-entry-get nil property)
> 		  ;; is it non-empty?
> 		  valflag (and val (string-match "\\S-" val))
> 		  ;; current property value as number (or nil if empty)
> 		  curval (if valflag (org-column-string-to-number val format) nil)
> 		  ;; get values to replace current value and running total
> 		  newvals (if uselisp (eval-expression (read form))
> 			    (list (or prevtotal curval 0)
> 				  (+ curtotal (or prevtotal curval 0)))))
> 	    (cond
> 	     ((< level last-level) ; we have moved up to a parent
> 	      (setq
> 	       ;; new value, as string
> 	       str (if (nth 0 newvals) (org-columns-number-to-string (nth 0  
> newvals) format printf) nil)
> 	       ;; add text properties to it
> 	       useval (org-add-props (copy-sequence str) nil 'org-computed  
> t 'face 'bold)
> 	       ;; get current text properties
> 	       sum-alist (get-text-property sumpos 'org-summaries))
> 	      ;; put new value here as a text property
> 	      (if (assoc property sum-alist)
> 		  (setcdr (assoc property sum-alist) useval)
> 		(push (cons property useval) sum-alist)
> 		(org-unmodified
> 		 (add-text-properties sumpos (1+ sumpos)
> 				      (list 'org-summaries sum-alist))))
> 	      ;; put new org property value
> 	      (if (nth 0 newvals) (org-entry-put nil property str))
> 	      ;; set value for current level total
> 	      (when (or prevtotal valflag)
> 		(aset lsum level (nth 1 newvals)))
> 	      ;; clear totals for deeper levels
> 	      (loop for l from (1+ level) to (1- lmax) do
> 		    (aset lsum l (if uselisp nil 0))))
> 	     ((>= level last-level) ; we have not moved up to a parent
> 	      ;; set new org property value and add to total for this level
> 	      (org-entry-put nil property (org-columns-number-to-string  
> (nth 0 newvals) format printf))
> 	      (aset lsum level (nth 1 newvals)))
> 	     (t (error "This should not happen")))))
>      (org-columns-compute-orig property))))
>
>
>
> -- 
> aleblanc
>
>
>
> _______________________________________________
> Emacs-orgmode mailing list
> Remember: use `Reply All' to send replies to the list.
> Emacs-orgmode@gnu.org
> http://lists.gnu.org/mailman/listinfo/emacs-orgmode

=======================
PLEASE NOTE NEW ADDRESS
=======================
prof.dr. Carsten Dominik				dominik@uva.nl
Astronomical Institute 'Anton Pannekoek' 	 	www.astro.uva.nl/~dominik
Faculty of Science, University of Amsterdam		phone 	+31-20-5257477/7491
SCIENCE PARK 904, ROOM C4-106			fax   	+31-20-5257484
1098 XH Amsterdam, The Netherlands
mail: PO BOX 94249, 1090GE, Amsterdam

      reply	other threads:[~2009-06-09 10:10 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-13 23:43 SOLVED: elisp formulas in column view (without converting to tables) news
2009-03-14  1:33 ` news
2009-03-16 20:15 ` news
2009-06-09  6:26   ` Carsten Dominik [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3242F661-56E9-4073-9308-762DEB5F25B7@uva.nl \
    --to=dominik@uva.nl \
    --cc=emacs-orgmode@gnu.org \
    --cc=news@aleblanc.cotse.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).