Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Implementing the Martini method, I'd like to count the number of words added to a file since last checkpoint (say, each day).

I guess I could count the words of an older backed-up version, count the words in the current version, and difference, but it sounds like much processing is useless, and there are files to manage in the way.

Is there a way to count this on the way, that is, have a progressive count that takes all input into account, and that I would be able to reset at any point ?

I don't mind it dying between sessions. I see yanking as a possible issue, but mostly I have no idea about how to process the input rather than file diffs.

share|improve this question

You should be able to call a word count function the first time you open an emacs session and save the result into a variable. Then, you can run the word count command again and process the result to get the number of words added.

I gave this a go but my emacs-lisp foo is pitiful. If you are more knowledgeable of and comfortable with emacs-lisp than I, you should be able to edit this word count function to suit your needs. Please post back here if you do, I'd like to see how :).

I got the function and some other useful information from the emacs wiki word count page.

If an emacs-less solution is acceptable, you could try adding these lines to your ~/.bashrc:

function start_count(){
  wc -w $1 | cut -f 1 -d" " > ~/.count; 
  emacs $1
function show_progress(){
    p=`cat ~/.count`; 
    c=`wc -w $1  | cut -f 1 -d" "`; 
    echo "You have written "$(($c-$p))" words today!"

Now, when you start working, you open your file for editing and save its current word count into ~/.count like so:

start_count file.txt

When you want to check your progress just run :

show_progress file.txt

Bear in mind that this will treat LaTeX control sequences as words, so the count might not be perfect. Don't know how to get around that though...

share|improve this answer
I'll read into more detail tonight, but that'll go with free text in org-mode, LaTeX sequences won't be an issue for now. Moreover, once the “update” part is managed, I guess it should be easy to replace wc by some count-true-words-lost-in-markup function for any markup language, for which I saw a few answers already existed. – Nikana Reklawyks Dec 2 '12 at 18:06
Ok so tonight became yet another asap, but here's the update :·) Thanks a lot for your ideas. Oh, and my elisp got a lot better tonight thanks to that =) – Nikana Reklawyks Dec 5 '12 at 8:00
up vote 1 down vote accepted

Following is what I came up with, following terdon's ideas.

I'm pretty happy with it, it does what I wanted, over a few files in the my-martini-files variable.

Edit : A temporary count has been added, which allows to stack progress, and still reset the count sometimes, not to take heavy copy/paste that shouldn't add words into account for the progress achieved.

I bound it to f4 for a report, C-f4 to re-initialize the count (of files), S-f4 to stack progress, and C-S-f4 to start a new day, all counts at 0.

Fanciness would now consist in integrating it to the modeline, but that's another matter.

;; Teh Martini method
(require 'wc) ; The file terdon links to.
(defun wc-in-buffer (file)
  "Return the number of words in the buffer opening the file
passed as an argument. It should already be open."
  (with-current-buffer (get-file-buffer file)
    (wc-non-interactive (point-min) (point-max)))
(defun my-martini-sum ()
  "Sum words over my-martini-files."
  (apply '+ 
     (loop for file in my-martini-files
        collect (wc-in-buffer file)))
(setq my-martini-files '("~/path/to/"
                         ;; Taken from org-agenda-files

(defun my-martini-update () "Update my-martini-count from files." (interactive) (setq my-martini-count (my-martini-sum)) (message "Files lengths updated.")) (defun my-martini-reset () "Reset counts and stack for a new day." (interactive) (my-martini-update) (setq my-martini-stack 0) (message "Martini counts re-initialized.")) (defun my-martini-stack () "Stack the current progress, and update. To be used before pasting loads of unsignificant words." (interactive) (setq my-martini-stack (+ my-martini-stack (- (my-martini-sum) my-martini-count))) (message "Current count is stacked. Mess at will, just update afterwards.") ) (defun my-martini-report () "Display changes in total word count since last update." (interactive) (message (concat "As for now, " (number-to-string (+ my-martini-stack (- (my-martini-sum) my-martini-count))) " new words have been added today.")) ) (global-set-key [f4] 'my-martini-report) (global-set-key [\C-f4] 'my-martini-update) (global-set-key [\S-f4] 'my-martini-stack) (global-set-key [\C-\S-f4] 'my-martini-reset)

Any comments or suggestions to improve the code are dearly welcome.

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .