0

(I'm aware of "Creating timestamps", but my point is to automatically update such timestamps distributed in several places in the file.)

I'd like to have in a org-mode file a kind of placeholder for the current date (at the YYYY-MM-DD format), which is automatically updated when the file is saved.

Is it possible?

Edit

Here is the context of my question: I'm in the process of writing a LaTeX class using org-babel for the literate programming. In several places of the file .org file, I have to insert the release date of this class, at least in the exported README.md file like this:

Release
-------
2021-05-10 v1.0.0-alpha

and in the exported .cls source file of the class, like this:

\ProvidesExplPackage{my-nice-class}
{2021-05-10}
{v1.0.0-alpha}
{
  Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
}

Because I'm likely to forget to update this date before the actual release, I'd like it to be automatically updated each time the .org file is saved.

2
  • Sigh - you ask one question, you get an answer to that question and now you change the question to a completely different one. Please don't do that: ask a separate question instead.
    – NickD
    Commented May 10, 2021 at 13:25
  • @NickD Sorry, I didn't I feel this was a completely different question. I asked a new one: Automatically update a date in tangled files of an .org file?. Commented May 10, 2021 at 14:28

2 Answers 2

2

time-stamp, which comes with Emacs by default, will allow you to do exactly what you want with the appropriate settings. E.g. I have:

# Local Variables:
# time-stamp-line-limit: 1000
# time-stamp-format: "[%Y-%m-%d %H:%M]"
# time-stamp-active: t
# time-stamp-start: "version = \""
# time-stamp-end: "\""
# End:

in some of my org files.

After adding time-stamp to the before-save-hook:

(add-hook 'before-save-hook #'time-stamp)

and with the above settings, a template like this:

# version = ""

will be filled out like this:

# version = "[2021-05-15 11:34]"

1

I think there are better methods to keep track of the modification time of the file: e.g. ls -l on the directory will tell you exactly what you are asking: the time that the file was last modified. Even better, keep it under source control and then you'll know every change, as well as when that change was made. THe point is that the modification time is metadata and should be treated as such. If you put the timestamp in the file, then it's part of the data that the file stores. IMO, that's the wrong place for it.

Be that as it may, if you still insist of keeping a time stamp in the file, you can use before-save-hook to run an arbitrary function just before the file is saved. The function can e.g. check that this is an Org mode file and replace every occurrence of some placeholder with the current time and date. What I'm implementing here is sort-of what the old RCS system did: it looked for lines of the form

$foo: bar$

where foo is an RCS keyword and it would replace the RHS (the part after the colon with some calculated value. Initially, you could just say $foo$ and RCS would expand the keyword with a value as above. Then the value would change, depending on what RCS calculated for it.

So the idea here is to have a keyword TS in your Org mode file:

* foo

$TS$

and when the file gets saved, the keyword is expanded to:

* foo

$TS: Sat May  8 19:26:46 2021$

Here's the implementation:

(defvar ndk/ts-placeholder-re "$TS:?[^$]*\\$")

(defun ndk/ts-placeholder-replace ()
  (when (eq major-mode 'org-mode)
    (let ((ts (current-time-string)))
      (replace-regexp ndk/ts-placeholder-re (format "$TS: %s$" ts) nil (point-min) (point-max)))))

(add-hook 'before-save-hook #'ndk/ts-placeholder-replace)

The regexp matches $TS$ as well as the expanded form $TS: Sat May 8 19:26:46 2021$, so the keyword is expanded in either case.

The function checks that this is an Org mode file (you can check for other modes or delete the check altogether, depending on your needs). It then looks for the regexp and replaces every occurrence with the result of calling the function current-time-string. You can replace that with a different function that returns a string of the timestamp in your preferred format. For example

(format-time-string "%Y-%m-%dT%H:%M:%S" (current-time)) => "2021-05-08T19:41:22"

See the doc string of format-time-string for the gory details: C-h f format-time-string.


EDIT: A better answer to this question is given by @Tyler at https://emacs.stackexchange.com/a/64789/14825

1
  • About the "better methods to keep track of the modification time of the file", my point is not that one, and I should have explained the context, which is now the case. I guess it would be difficult to make regexp where the date has to be inserted. Commented May 10, 2021 at 7:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.