From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jonathan Leech-Pepin Subject: Re: building tagcloud datastructure in elisp Date: Wed, 12 Sep 2012 19:34:09 -0400 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Return-path: Received: from eggs.gnu.org ([208.118.235.92]:49636) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TBwRg-000503-Gk for emacs-orgmode@gnu.org; Wed, 12 Sep 2012 19:34:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TBwRf-0006Mt-8v for emacs-orgmode@gnu.org; Wed, 12 Sep 2012 19:34:12 -0400 Received: from mail-wi0-f171.google.com ([209.85.212.171]:49526) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TBwRe-0006Mp-Vo for emacs-orgmode@gnu.org; Wed, 12 Sep 2012 19:34:11 -0400 Received: by wibhq4 with SMTP id hq4so4897398wib.12 for ; Wed, 12 Sep 2012 16:34:09 -0700 (PDT) In-Reply-To: List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: Marcelo de Moraes Serpa Cc: Org Mode Hello Marcello, On 12 September 2012 14:41, Marcelo de Moraes Serpa wrote: > Hi list, > > How hard would it be to parse a bunch of org files and build an elisp data > structure (Hash?) that represents a tagcloud? All tags in all headlines and > subtrees should be taken into account (for all org files that are parsed). > Could I use org-element to help me parse this or is there a better way? > > I'm just learning the org API, and I've only done a bunch of elisp hacks, so > any insight would be greatly appreciated! I'm learning as well, mostly by providing a feature I could use, or by seeing a problem I find interesting and deciding I want to find a solution to it. > Thanks, > > - Marcelo. Org-element doesn't seem to include tag-inheritance when providing tags for a given headline, so counting inherited tags becomes slightly more complex. The following should provide what you want: #+begin_src emacs-lisp (defun zin/org-tag-cloud-freq (&optional inherit file) "Return an alist containing tag and frequency. When INHERIT is given, the frequency of a tag includes the number of subheadings (to indicate tag inheritance). FILE allows for an arbitrary file to be retrieved and used for tag counting." (interactive "P") (when file (find-file file)) (let* ((source (org-element-parse-buffer 'headline)) (tags (org-element-map source 'headline (lambda (headline) (let ((tags (org-export-get-tags headline source)) (count (if inherit (length (org-element-map headline 'headline 'identity)) 1))) (list tags count))))) taglist) (setq taglist (mapcar (lambda (s) (when (car s) (loop for item in (car s) collect (list item (cadr s))))) tags)) (setq taglist (loop for item in taglist append item)) (dolist (tag taglist result) (let* ((tagitem (car tag)) (tagcount (cadr tag)) (sofar (assoc tagitem result))) (if sofar (setcdr sofar (+ tagcount (cdr sofar))) (push (cons tagitem tagcount) result)))) (format "%s" result))) (defun zin/org-tag-freq-list (files &optional inherit) "List of files to be processed by `zin/org-tag-cloud-freq'. Returns a single alist of tag counts." (let (result) (dolist (file files result) (let ((entries (zin/org-tag-cloud-freq inherit file))) (loop for tag in entries do (let ((tagitem (car tag)) (tagcount (cdr tag)) (sofar (assoc tagitem result))) (if sofar (setcdr sofar (+ tagcount (cdr sofar))) (push (cons tagitem tagcount) result)))))) (format "%s" result))) #+end_src The dolist loop for counting the tags themselves comes from http://stackoverflow.com/questions/6050033/elegant-way-to-count-items. There may be a cleaner way to obtain the list of tags and associated counts but this provides the values. The first function will work on any Org buffer to return the list of tags while the second will do so for a list of org files (for example org-agenda-files). I hope this helps Regards, -- Jon