From mboxrd@z Thu Jan 1 00:00:00 1970 From: Adam Porter Subject: Re: org-word-count exemptions Date: Sat, 25 Jan 2020 02:15:16 -0600 Message-ID: <87wo9gt0iz.fsf@alphapapa.net> References: <874kwk9efb.fsf@skimble.plus.com> Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from eggs.gnu.org ([2001:470:142:3::10]:36421) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ivGbC-0000cJ-MH for emacs-orgmode@gnu.org; Sat, 25 Jan 2020 03:15:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ivGbB-0007tg-LA for emacs-orgmode@gnu.org; Sat, 25 Jan 2020 03:15:22 -0500 Received: from ciao.gmane.io ([159.69.161.202]:49826) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ivGbB-0007qY-F7 for emacs-orgmode@gnu.org; Sat, 25 Jan 2020 03:15:21 -0500 Received: from list by ciao.gmane.io with local (Exim 4.92) (envelope-from ) id 1ivGbA-000UHM-1Q for emacs-orgmode@gnu.org; Sat, 25 Jan 2020 09:15:20 +0100 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-mx.org@gnu.org Sender: "Emacs-orgmode" To: emacs-orgmode@gnu.org There are various solutions floating around. Here's one way: (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 () (unpackaged/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))))) (defun unpackaged/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)))