I have files such as these:
0000
0030
+ Something
+ Another thing
+ One more thing
0200
+ Something else
+ And one more thing
0230
In the above, the numbers represent time in HHMM
format. I want to transform it to:
0010 + Something
0020 + Another thing
0030 + One more thing
0115 + Something else
0200 + And one more thing
I will explain the transformation in the above example:
between
0030
and0200
there are 3 lines. And time difference between0000
and0030
is 30 minutes. So each item below0030
gets a 10 minutes increment starting from0000
. And thus the 3 new timestamps are0010
,0020
and0030
respectively.similarly between
0200
and0230
there are 2 lines. And the time difference between0030
and0200
is 90 minutes. So each item below0200
gets 45 minutes increment starting from0030
. So the 2 new timestamps are0115
and0200
respectively.
I have made some progress in writing an elisp-macro for this transformation task:
I could modify the answer to this emacs.stackexchange post to compute the time difference between times.
I could write a function that takes in time and minutes elapsed to print new time after adding elapsed minutes to time.
Now the only thing that I need to complete my recipe is: the number of items between two consecutive
HHMM
patterns so that I can split the difference of time evenly over the items.Lastly I plan to wrap up all the above inside a
(while (search-forward-regexp "pattern" nil :noerror)
to apply the above macros to everywhere applicable inside the file.
Here is the summary of my failed attempts so far:
I recorded a keyboard macro to mark the region between two consecutive HHMM
pattern and then I am trying to use (count-lines start end)
. However I get the error:
Symbol's value as a variable is void: start
Here is my code snippet for this attempt:
(defun timesheet-fill-times ()
(interactive)
(let (diff lines)
(setq diff (timesheet-time-diff))
(timesheet-mark-lines)
(setq lines (count-lines start end))
(message "%d diff %d lines" diff lines)
)
)
where timesheet-time-diff
is my elisp macro to compute time difference between consecutive patterns and timesheet-mark-lines
is my recorded keyboard macro to mark the relevant region. I tried to modify the function definition to: (defun timesheet-fill-times (start end) ;; rest of code )
. Now the error becomes:
Wrong number of arguments
However, strangely, the following works alright: I have defined this function:
(defun my-count-lines-region (start end)
(interactive "r")
(message "%d"
(count-lines start end)))
So if I keep my cursor on +
after 0030
and do M-x timesheet-mark-lines RET M-x my-count-lines-region RET
I get 3 as expected. And similarly with the cursor on +
after 0200
I get 2 as expected.
My other approach I thought of was that: I can match for the pattern HHMM - some lines - HHMM
by using something like this:
(re-search-forward (concat "^\\([0-2][0-9]\\)\\([0-5][0-9]\\)"
"\\(\\(.\\|[\n]\\)*?\\)"
"\\([0-2][0-9]\\)\\([0-5][0-9]\\)"
) nil :noerror)
Is there someway I can count the number of newline characters in that match?
I have tried my best but I feel stuck. Please advice.
count-words-region
. Despite its name, it also gives you the number of lines is the region.match-string 0
. You will find what exactly this pattern matches to (which does not include multiple lines). Otherwise you couldsplit-string
on\n
and get thelength
of the resulting list. You can test your regexp with theregexp-builder
.