Search code examples
emacsorg-mode

How to count characters of a subtree in emacs org mode?


I would like to count characters in a subtree (heading) in org mode. Right now I have figured out how to count characters in a single paragraph, but not over multiple paragraphs. I first define a source block:

#+NAME: countChars
#+BEGIN_SRC sh :var X="" :results output
echo "$X" | wc --chars
#+END_SRC

And then I use it on named paragraphs:

#+NAME: paragraph
This is the paragraph

#+CALL: countChars(paragraph)

This works well but the #+NAME: only covers one paragraph. I have tried to use a heading as argument but I could not make it work.

EDIT: Based on comments, I came up with:

#+NAME: countChars
#+BEGIN_SRC emacs-lisp :results output :eval no-export :exports results
(interactive)
(save-excursion
  (org-mark-subtree)
  (setq a (- (mark) (point)))
  (deactivate-mark)
  (prin1 'Count= )
  (prin1 a))
#+END_SRC

which does almost what I want when invoked as

#+CALL: countChars()

but has the problem of counting source code blocks (including itself) as well as text. I would like to count text only (excluding the headline).


Solution

  • You can only use #+NAME in front of a source block, not a subtree.

    It's easier to write this in emacs lisp.

    This code block will count the number of characters in the current subtree, not including the header or the last line of the content: If you want to count the number of characters in the current subtree using emacs lisp, try this:

    (save-excursion
      (org-mark-subtree) ;mark the whole subtre
      (forward-line 1)   ;move past header
      (exchange-point-and-mark) ;swap point and mark (ends of region)
      (forward-line -1)  ;move backwards past the last line
      (let ((nchars (- (point) (mark))))
        (deactivate-mark) ;clear the region
        (message "%d" nchars))))