bastibe / org-static-blog

A static site generator using org-mode
BSD 3-Clause "New" or "Revised" License
341 stars 74 forks source link

Perhaps use `org-collect-keywords` to extract date? #131

Closed Dou-Meishi closed 9 months ago

Dou-Meishi commented 9 months ago

Hello, this is a great package! I always want to build my blog site but have no courage to learn thhose heavy SSG tools, especially their template language. Several days ago when I was searching the usage of org-publish I found this package and I knew this is exactly what I want.

These days I have been exploring this package by following your demo and others configuration and trying to generate my site in my computer. Everything works fine except that the post date was always set to the current time, instead of the value specified by #+DATE. Thanks to your clear code organization, it did not take me much time to locate the bug. The current implementation of org-static-blog-get-date is based on the following REGEXP

(search-forward-regexp "^\\#\\+date:[ ]*<\\([^]>]+\\)>$" nil t)

It works fine for active timestamp like <2024-01-24> but does not match inactive timestamp like [2024-01-24] or the bare string 2024-01-24. Sadly, none of my org notes uses active timestamps.

I am not very familiar with REGEXP in elisp but I think the function org-collect-keywords can extract the value of #+DATE easily. It is also case-insensitive and can match #+date. I create a small org file and test on different values of date (absent, 2024-01-01, <2024-01-01>, [2024-01-01]) and find out it works well.

#+TITLE: Alternative implementation of get-date
#+AUTHOR: Dou Meishi
#+DATE: [2024-01-01]

#+BEGIN_SRC elisp
(defun dms/org-static-blog-get-date (post-filename)
  "Extract the `#+date:` from POST-FILENAME as date-time."
  (with-temp-buffer
    (insert-file-contents post-filename)
    (let* ((postdate (cadar (org-collect-keywords '("date")))))
      (if postdate (date-to-time postdate) (time-since 0)))))

(format-time-string "%Y-%m-%d" (org-static-blog-get-date (buffer-file-name)))

(format-time-string "%Y-%m-%d" (dms/org-static-blog-get-date (buffer-file-name)))
#+END_SRC

Interestingly, org-collect-keywords seems to be able to ignore #+date appears in source blocks or example blocks.

bastibe commented 9 months ago

Thank you for the bug report. It seems that the timestamp regex is a bit broken anyway.

How about this version:

(search-forward-regexp "^\\#\\+date:[ ]*[[<]?\\([^]>]+\\)[]>]?$" nil t)

This should skip any <[ at the beginning of the timestamp, and any >] at the end, and work without any delimiters as well. Does that work on your end?

I'd prefer to not use the org- functionality, as it is very slow.

Dou-Meishi commented 9 months ago

Great! I tested on the previous simple document and it worked as expected, including 2024-01-01, [2024-01-01], <2024-01-01> and nil.

bastibe commented 9 months ago

Wonderful! Since you started this issue, would you like to contribute the change as a pull request?

Dou-Meishi commented 9 months ago

Wonderful! Since you started this issue, would you like to contribute the change as a pull request?

I am glad to do it!

bastibe commented 9 months ago

Thank you very much for your contribution!