一种维护ox-hugo索引的方式

ox-hugo 官网介绍了两种维护博文索引的方法:

一种是某一个Section下所有的博文写在同一个org文件里面。每一篇文件是一个Subtree。更新的时候选一个Subtree导出。这种方法的好处是所有的subtree可以共享一些元属性(例如 HUGO_BASE_DIR 等等)。 ox-hugo 作者推荐使用这种方法。

另一种是每一篇博文单独写一个org文件。好处是很符合直觉,我自己比较喜欢这种方式。缺点是元信息每一个org文件都要单独维护,即便是这些文件的元信息是共享的。虽然创建的时候可以用模板,元信息出现变更的时候还是会蛋疼。

面对这种两难选择,我只想说: 我全都要.jpg。 org-mode 是支持内嵌另一个org文件的。我的搞法是维护一个index.org,每一个subtree下面用 include 来填充真正的org文件。当然,当具体的博文org文件信息改变时,还是需要来通知index更新信息,并重新导出当前subtree的。手动搞就很麻烦,所以我写了一个方法献给有缘人,更改后调用 my/org-update-index 就可以了。

(defun my/org-global-keyword-value-current-buffer (key)
  (car (org-element-map (org-element-parse-buffer) 'keyword
         (lambda (el) (when (string-equal (org-element-property :key el) (upcase key))
                        (org-element-property :value el))))))

(defun my/org-date-extract (str)
  (when (string-match (rx (zero-or-more "<")
                          (group (one-or-more (or digit "-")))
                          (zero-or-more ">"))
                      str))
  (match-string 1 str))

(defun my/org-update-index ()
  (interactive)
  (save-window-excursion
    (let* ((title (my/org-global-keyword-value-current-buffer "title"))
           (indexEntry (concat "* " title "\n"
                               ":PROPERTIES:\n"
                               ":EXPORT_DATE: " (my/org-date-extract (my/org-global-keyword-value-current-buffer "date")) "\n"
                               ":EXPORT_FILE_NAME: " (file-name-base (buffer-file-name)) "\n"
                               ":END:\n"
                               "#+INCLUDE: ./" (file-name-nondirectory (buffer-file-name)) "\n"))
           (filename (file-name-base (buffer-file-name)))
           )

      (find-file "./index.org")
      (let* ((pos-cons (org-element-map (org-element-parse-buffer 'headline) 'headline
                         (lambda (body)
                           (when (string-equal (org-element-property :EXPORT_FILE_NAME body) filename)
                             (org-element-property :begin body))
                           ))))
        (if pos-cons
            (let ((pos (car pos-cons)))
              (progn
                (goto-char pos)
                (org-mark-subtree)
                (delete-region (region-beginning) (region-end))
                (message (format "removed existing index for title %s" title))
                ))
          (goto-char (point-max))
          )
        (insert indexEntry)
        (org-goto-marker-or-bmk (org-find-exact-headline-in-buffer title))
        (org-hugo-export-wim-to-md)
        (save-buffer)
        (kill-current-buffer)
        ))
    )
  )

目前支持title和date属性,支持其他的属性稍微改改应该也不难。鉴于本人菜鸟级的elisp水平,难免有脱裤子放屁的行为,请各位指正。

1 个赞

实在不能理解,图啥呢?

舒适啊~又可以把所有共享的属性放在一起,又可以每篇文章单独放一个org file。满足了本人的强迫症。