orgzly / orgzly-android

Outliner for taking notes and managing to-do lists
https://www.orgzly.com
GNU General Public License v3.0
2.68k stars 304 forks source link

Provide alternative to non-standard CREATED property #1053

Open grothesque opened 6 months ago

grothesque commented 6 months ago

Orgzly defaults to creating a CREATED property for each new note.

As far as I can see the CREATED property is not standard. It is not listed among orgmode's special properties. The term CREATED does not even occur in Orgmode's source code.

I believe that the CREATED property convention might have been introduced by the org-expiry.el contributed package.

Orgzly's configuration allows to change the name of the property from CREATED to something else, but it must always be a property. This is not idiomatic in org, where the official documentation suggests simply using an inactive timestamp for saving the creation time of a note.

As far as I can see users who would like to follow this recommendation are unable to do so with Orgzly. It can be annoying to have to manually edit each note taken in Orgzly if one values a consistent format and one does not follow Orgzly's convention.

nick4f42 commented 4 months ago

Just adding my two cents here, but I think a CREATED property is better than just including the timestamp in the headline contents.

There is the TIMESTAMP_IA special property which selects the first inactive timestamp, but it might not select the timestamp you want. For example, the timestamp in a note added with org-add-note is chosen first.

All that being said, I do think Orgzly should have an option to put the creation timestamp in the content for people who prefer it that way.

For anyone that wants to migrate to the CREATED property way, I'll share what I ended up doing. First, you can make sure new captured notes have the CREATED property with :hook in the capture template:

(defun my-org-entry-put-created ()
  "Add a CREATED property with the current date and time."
  (interactive nil org-mode)
  (let ((prop "CREATED"))
    (if (org-entry-get (point) prop)
        (user-error "%s property already exists" prop))
    (org-entry-put
     (point) prop
     (format-time-string (org-time-stamp-format 'with-time 'inactive)))))

(setopt org-capture-templates
        '(("t" "Task" entry
           (file "")
           "* TODO %?\n\n%i"
           :empty-lines 1
           :hook my-org-entry-put-created)
          ("n" "Note" entry
           (file "")
           "* %?\n%i"
           :empty-lines 1
           :hook my-org-entry-put-created)))

Then, to convert old headlines to the new format, you can use this command. Make sure to diff-buffer-with-file to check the changes before saving. Also be aware that it doesn't detect timestamps in headlines where a note was added with org-add-note when org-log-into-drawer was nil.

(defun my-org-propertize-timestamps (&optional property)
  "Convert beginning of content timestamps to properties."
  (interactive nil org-mode)
  (or property (setq property "CREATED"))
  (org-map-entries
   (lambda ()
     (let ((entry (point-marker)))
       (unless (org-entry-get entry property)
         (org-end-of-meta-data 'full)
         ;; When the first line of content is an org timestamp, convert
         ;; it to a property.
         (if (looking-at org-tsr-regexp-both)
             (atomic-change-group
               (let* ((beg (match-beginning 0))
                      (end (match-end 0))
                      (ts (delete-and-extract-region beg end)))
                 (when (eolp)
                   (delete-char 1))
                 (org-entry-put entry property ts)))))))))
grothesque commented 4 months ago

Nick, thanks for your comment and the attached code.

Just adding my two cents here, but I think a CREATED property is better than just including the timestamp in the headline contents.

If you think that your arguments are strong enough, I suggest that you raise this issue on the org mailing list and try to make the CREATED property officially endorsed in some way.

Otherwise, Orgzly introduces an (arguably minor) incompatibility into the org-o-sphere.