From mboxrd@z Thu Jan 1 00:00:00 1970 From: Adam Porter Subject: New org-count-words function Date: Tue, 12 Jun 2018 14:58:00 -0500 Message-ID: <87602nrd4n.fsf@alphapapa.net> Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:44759) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fSpQn-0002tO-5K for emacs-orgmode@gnu.org; Tue, 12 Jun 2018 15:58:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fSpQi-0000DV-AA for emacs-orgmode@gnu.org; Tue, 12 Jun 2018 15:58:17 -0400 Received: from [195.159.176.226] (port=45351 helo=blaine.gmane.org) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fSpQi-0000DC-23 for emacs-orgmode@gnu.org; Tue, 12 Jun 2018 15:58:12 -0400 Received: from list by blaine.gmane.org with local (Exim 4.84_2) (envelope-from ) id 1fSpOW-0000nj-Sq for emacs-orgmode@gnu.org; Tue, 12 Jun 2018 21:55:56 +0200 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" To: emacs-orgmode@gnu.org Hi friends, Here's a new function that counts lines, words, and characters in the region or the subtree at point. It prints a message like `count-words` does, like: Subtree "Heading" has 7 line, 5 words, and 28 characters. Note that it does *not* count words in heading lines, planning lines, and drawers, so it gives a more useful count for the "prose" in the subtree. Here's the code: #+BEGIN_SRC elisp (defun ap/org-count-words () "If region is active, count words in it; otherwise count words in current subtree." (interactive) (if (use-region-p) (funcall-interactively #'count-words-region (region-beginning) (region-end)) (org-with-wide-buffer (cl-loop for (lines words characters) in (org-map-entries (lambda () (ap/org-forward-to-entry-content 'unsafe) (let ((end (org-entry-end-position))) (list (count-lines (point) end) (count-words (point) end) (- end (point))))) nil 'tree) sum lines into total-lines sum words into total-words sum characters into total-characters finally do (message "Subtree \"%s\" has %s lines, %s words, and %s characters." (org-get-heading t t) total-lines total-words total-characters))))) #+END_SRC It requires this supporting function: #+BEGIN_SRC elisp (defun ap/org-forward-to-entry-content (&optional unsafe) "Skip headline, planning line, and all drawers in current entry. If UNSAFE is non-nil, assume point is on headline." (unless unsafe ;; To improve performance in loops (e.g. with `org-map-entries') (org-back-to-heading)) (cl-loop for element = (org-element-at-point) for pos = (pcase element (`(headline . ,_) (org-element-property :contents-begin element)) (`(,(or 'planning 'property-drawer 'drawer) . ,_) (org-element-property :end element))) while pos do (goto-char pos))) #+END_SRC I think it's an improvement over the functions I've seen that do this. Hope someone finds it useful.