summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/hugo-config.el124
-rw-r--r--modules/org-export-config.el30
-rw-r--r--modules/user-constants.el3
3 files changed, 127 insertions, 30 deletions
diff --git a/modules/hugo-config.el b/modules/hugo-config.el
new file mode 100644
index 00000000..8bc2cef2
--- /dev/null
+++ b/modules/hugo-config.el
@@ -0,0 +1,124 @@
+;;; hugo-config.el --- Hugo Blog Configuration -*- lexical-binding: t; coding: utf-8; -*-
+;; author: Craig Jennings <c@cjennings.net>
+
+;;; Commentary:
+;; Integrates ox-hugo for publishing Org files to a Hugo website.
+;;
+;; One-file-per-post workflow:
+;; - Each blog post is a standalone Org file in content-org/log/
+;; - File-level keywords control Hugo front matter
+;; - Export with C-; h e, create new posts with C-; h n
+;;
+;; Keybindings (C-; h prefix):
+;; - C-; h n : New post (create from template)
+;; - C-; h e : Export current post to Hugo markdown
+;; - C-; h o : Open blog source directory in dirvish
+;; - C-; h O : Open blog source directory in system file manager
+;; - C-; h d : Toggle draft status (TODO/DONE)
+
+;;; Code:
+
+(require 'user-constants)
+(require 'host-environment)
+
+;; --------------------------------- Constants ---------------------------------
+
+(defconst cj/hugo-content-org-dir
+ (expand-file-name "content-org/log/" website-dir)
+ "Directory containing Org source files for Hugo blog posts.")
+
+;; ---------------------------------- ox-hugo ----------------------------------
+
+(use-package ox-hugo
+ :after ox)
+
+;; ----------------------------- Hugo Blog Functions ---------------------------
+
+(defun cj/hugo-new-post ()
+ "Create a new Hugo blog post as a standalone Org file.
+Prompts for title, generates the slug filename, and opens the
+new file with Hugo front matter keywords pre-filled."
+ (interactive)
+ (require 'ox-hugo)
+ (let* ((title (read-from-minibuffer "Post Title: "))
+ (slug (org-hugo-slug title))
+ (date (format-time-string "%Y-%m-%d"))
+ (file (expand-file-name (concat slug ".org") cj/hugo-content-org-dir)))
+ (when (file-exists-p file)
+ (user-error "Post already exists: %s" file))
+ (unless (file-directory-p cj/hugo-content-org-dir)
+ (make-directory cj/hugo-content-org-dir t))
+ (find-file file)
+ (insert (format "#+hugo_base_dir: ../../
+#+hugo_section: log
+#+hugo_auto_set_lastmod: t
+#+title: %s
+#+date: %s
+#+hugo_tags:
+#+hugo_draft: true
+#+hugo_custom_front_matter: :description \"\"
+
+" title date))
+ (save-buffer)
+ (message "New post: %s" file)))
+
+(defun cj/hugo-export-post ()
+ "Export the current Org file to Hugo-compatible Markdown."
+ (interactive)
+ (require 'ox-hugo)
+ (unless (derived-mode-p 'org-mode)
+ (user-error "Not in an Org buffer"))
+ (org-hugo-export-to-md)
+ (message "Exported: %s" (buffer-name)))
+
+(defun cj/hugo-open-blog-dir ()
+ "Open the blog source directory in dirvish/dired."
+ (interactive)
+ (unless (file-directory-p cj/hugo-content-org-dir)
+ (make-directory cj/hugo-content-org-dir t))
+ (dired cj/hugo-content-org-dir))
+
+(defun cj/hugo-open-blog-dir-external ()
+ "Open the blog source directory in the system file manager."
+ (interactive)
+ (unless (file-directory-p cj/hugo-content-org-dir)
+ (make-directory cj/hugo-content-org-dir t))
+ (let ((cmd (cond
+ ((env-macos-p) "open")
+ ((env-windows-p) "explorer.exe")
+ (t "xdg-open"))))
+ (start-process "hugo-file-manager" nil cmd cj/hugo-content-org-dir)))
+
+(defun cj/hugo-toggle-draft ()
+ "Toggle the draft status of the current Hugo post.
+Switches #+hugo_draft between true and false."
+ (interactive)
+ (save-excursion
+ (goto-char (point-min))
+ (if (re-search-forward "^#\\+hugo_draft: *\\(true\\|false\\)" nil t)
+ (let ((current (match-string 1)))
+ (replace-match (if (string= current "true") "false" "true") t t nil 1)
+ (save-buffer)
+ (message "Draft: %s → %s" current
+ (if (string= current "true") "false" "true")))
+ (user-error "No #+hugo_draft keyword found in this file"))))
+
+;; -------------------------------- Keybindings --------------------------------
+
+(global-set-key (kbd "C-; h n") #'cj/hugo-new-post)
+(global-set-key (kbd "C-; h e") #'cj/hugo-export-post)
+(global-set-key (kbd "C-; h o") #'cj/hugo-open-blog-dir)
+(global-set-key (kbd "C-; h O") #'cj/hugo-open-blog-dir-external)
+(global-set-key (kbd "C-; h d") #'cj/hugo-toggle-draft)
+
+(with-eval-after-load 'which-key
+ (which-key-add-key-based-replacements
+ "C-; h" "hugo blog menu"
+ "C-; h n" "new post"
+ "C-; h e" "export post"
+ "C-; h o" "open in dirvish"
+ "C-; h O" "open in file manager"
+ "C-; h d" "toggle draft"))
+
+(provide 'hugo-config)
+;;; hugo-config.el ends here
diff --git a/modules/org-export-config.el b/modules/org-export-config.el
index 2e921174..33e170f5 100644
--- a/modules/org-export-config.el
+++ b/modules/org-export-config.el
@@ -144,36 +144,6 @@
(?d "to docx and open" org-pandoc-export-to-docx-and-open)
(?z "to pdf and open (Zathura)" my/org-pandoc-export-to-pdf-and-open))))
-;; ---------------------------------- ox-hugo ----------------------------------
-;; Export Org subtrees to Hugo-compatible Markdown.
-;; Each Org heading with :EXPORT_FILE_NAME: becomes a separate Hugo post.
-;; Source file: ~/projects/website/content-org/log.org
-
-(use-package ox-hugo
- :after ox
- :config
- (defvar org-capture-templates)
-
- (defun cj/org-hugo-new-post-capture-template ()
- "Return a new Hugo post subtree template for org-capture.
-Prompts for title, generates slug, and sets export date to today."
- (let* ((title (read-from-minibuffer "Post Title: "))
- (fname (org-hugo-slug title)))
- (mapconcat #'identity
- `(,(concat "* TODO " title)
- ":PROPERTIES:"
- ,(concat ":EXPORT_FILE_NAME: " fname)
- ,(concat ":EXPORT_DATE: "
- (format-time-string "%Y-%m-%d"))
- ":END:"
- "%?\n")
- "\n")))
-
- (add-to-list 'org-capture-templates
- '("h" "Hugo post" entry
- (file "~/projects/website/content-org/log.org")
- (function cj/org-hugo-new-post-capture-template))))
-
;; github flavored markdown
;; (use-package ox-gfm
;; :after ox)
diff --git a/modules/user-constants.el b/modules/user-constants.el
index 85890f97..bae34bfe 100644
--- a/modules/user-constants.el
+++ b/modules/user-constants.el
@@ -119,6 +119,9 @@ Used by transcription module and other audio-related functionality.")
(defconst music-dir (expand-file-name "music/" user-home-dir)
"The location to save your music files.")
+(defconst website-dir (expand-file-name "projects/website/" user-home-dir)
+ "Root directory of the Hugo website project.")
+
;; FILES
(defvar authinfo-file (expand-file-name ".authinfo.gpg" user-home-dir)