From 7cc1e86114bfe1127f8b4698583e36162c77748b Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Sat, 14 Aug 2021 18:00:12 -0500 Subject: Merge `acdw-org/count-words' and `acdw-org/count-words-stupidly' I kept the second name, because really, it is a stupid function. --- lisp/acdw-org.el | 97 +++++++++++++++++--------------------------------------- 1 file changed, 29 insertions(+), 68 deletions(-) (limited to 'lisp/acdw-org.el') diff --git a/lisp/acdw-org.el b/lisp/acdw-org.el index 189ac67..f8f23c6 100644 --- a/lisp/acdw-org.el +++ b/lisp/acdw-org.el @@ -243,74 +243,13 @@ the deletion might narrow the column." (org-table-copy-down n) (acdw-org/return-dwim n))) -(defun acdw-org/count-words (start end) - "Count words between START and END, respecting `org-mode' conventions." - (interactive (list nil nil)) - (require 'cl-lib) - (require 'ox) - (message "Counting words...") - (cond ((not (called-interactively-p 'any)) - (let ((words 0)) - (save-excursion - (save-restriction - (narrow-to-region start end) - (goto-char (point-min)) - (while (< (point) (point-max)) - (cond - ;; Ignore comments - ((or (org-at-comment-p) - (org-in-commented-heading-p)) nil) - ;; Ignore tables - ((org-at-table-p) nil) - ;; Ignore hyperlinks, but count the descriptions - ((looking-at org-bracket-link-analytic-regexp) - (when-let ((desc (match-string-no-properties 5))) - (save-match-data - (setq words (+ words - (length (remove "" - (org-split-string - desc "\\W"))))))) - (goto-char (match-end 0))) - ;; Ignore source code blocks - ((org-in-src-block-p) nil) - ;; Ignore footnotes - ((or (org-footnote-at-definition-p) - (org-footnote-at-reference-p)) - nil) - ;; else... check the context - (t (let ((contexts (org-context))) - (cond - ;; Ignore tags, TODO keywords, etc. - ((or (assoc :todo-keyword contexts) - (assoc :priority contexts) - (assoc :keyword contexts) - (assoc :checkbox contexts)) - nil) - ;; Ignore sections tagged :no-export - ((assoc :tags contexts) - (if (cl-intersection (org-get-tags-at) - org-export-exclude-tags - :test 'equal) - (org-forward-same-level 1) - nil)) - ;; else... count the word - (t (setq words (1+ words))))))) - (re-search-forward "\\w+\\W*"))) - words))) - ((use-region-p) - (message "%d words in region" - (acdw-org/count-words (region-beginning) (region-end)))) - (t - (message "%d words in buffer" - (acdw-org/count-words (point-min) (point-max)))))) - ;; This isn't the best code, but it'll do. (defun acdw-org/count-words-stupidly (start end &optional limit) "Count words between START and END, ignoring a lot. Since this function is, for some reason, pricy, the optional parameter LIMIT sets a word limit at which to stop counting. -Once the function hits that number, it'll return \"-LIMIT\" +Once the function hits that number, it'll return -LIMIT instead of the true count." (interactive (list nil nil)) (cond ((not (called-interactively-p 'any)) @@ -334,13 +273,35 @@ instead of the true count." ((or (looking-at org-drawer-regexp) (looking-at org-clock-drawer-re)) (search-forward ":END:" nil :noerror)) + ;; Ignore tables + ((org-at-table-p) (forward-line)) + ;; Ignore hyperlinks, but count the descriptions + ((looking-at org-bracket-link-analytic-regexp) + (when-let ((desc (match-string-no-properties 5))) + (save-match-data + (setq words (+ words + (length (remove "" + (org-split-string + desc "\\W"))))))) + (goto-char (match-end 0))) + ;; Ignore source blocks + ((org-in-src-block-p) (foreward-line)) ;; Count everything else - (t (setq words (1+ words)) - (if (and limit - (> words limit)) - (setq words limit - continue nil)) - (forward-word-strictly)))))) + (t + ;; ... unless it's in a few weird contexts + (let ((contexts (org-context))) + (cond ((or (assoc :todo-keyword contexts) + (assoc :priority contexts) + (assoc :keyword contexts) + (assoc :checkbox contexts)) + (forward-word-strictly)) + + (t (setq words (1+ words)) + (if (and limit + (> words limit)) + (setq words (- limit) + continue nil)) + (forward-word-strictly))))))))) words)) ((use-region-p) (message "%d words in region" -- cgit 1.4.1-21-gabe81