You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
11 KiB
11 KiB
Org static blog
Vars and setup
(jao-load-path "org-static-blog")
(when (> emacs-major-version 26) (use-package htmlize :ensure t))
(defvar jao-blog-base-dir "~/doc/jao.io")
(defun jao-blog-dir (p) (expand-file-name p jao-blog-base-dir))
(setq jao-org-blog-tag-files
(seq-difference (directory-files (jao-blog-dir "blog") nil "tag-.*")
"tag-norss.html")
jao-org-blog-tags
(mapcar (lambda (f)
(string-match "tag-\\(.+\\)\\.html" f)
(format "<a href=\"/blog/%s\">%s</a>"
f (match-string 1 f)))
jao-org-blog-tag-files)
jao-org-blog-tag-rss
(mapcar (lambda (f)
(string-match "\\(.+\\)-rss\\.xml" f)
(format "<a href=\"/blog/%s\">%s</a>"
f (match-string 1 f)))
(directory-files (jao-blog-dir "blog") nil ".*-rss.xml"))
jao-org-blog-tag-names
(mapcar (lambda (f)
(string-match "tag-\\(.+\\)\\.html" f)
(match-string 1 f))
jao-org-blog-tag-files))
HTML headers and footers
Header
(setq org-static-blog-page-header
(concat
"<meta name=\"author\" content=\"jao\">\n"
"<meta name=\"referrer\" content=\"no-referrer\">\n"
"<link rel=\"stylesheet\" href=\"/static/style.css\""
" type=\"text/css\">\n"
"<link rel=\"apple-touch-icon\" sizes=\"180x180\""
" href=\"/static/apple-touch-icon.png\" >\n"
"<link rel=\"icon\" type=\"image/png\""
" sizes=\"32x32\" href=\"/static/favicon-32x32.png\">\n"
"<link rel=\"icon\" type=\"image/png\""
" sizes=\"16x16\" href=\"/static/favicon-16x16.png\">\n"
"<link rel=\"icon\" href=\"/static/favicon.ico\">\n"
"<link rel=\"manifest\" href=\"/static/site.webmanifest\">\n")
org-static-blog-page-preamble
(concat
"<div class=\"header\">"
" <a href=\"https://jao.io\">programming (and other) musings</a>"
" <div class=\"sitelinks\">"
" <a href=\"/blog/about.html\">about</a>"
" | <a href=\"/blog/hacking.html\">hacking</a>"
" | <a href=\"/blog/archive.html\">archive</a>"
" | <div class=\"dropdown\">"
" <a href=\"/blog/tags.html\" class=\"dropbtn\">tags</a>"
" <div class=\"dropdown-content\">"
(mapconcat #'identity jao-org-blog-tags "")
" </div>"
" </div>"
" | <div class=\"dropdown\">"
" <a href=\"/blog/rss.xml\" class=\"dropbtn\">rss</a>"
" <div class=\"dropdown-content\">"
(mapconcat #'identity jao-org-blog-tag-rss "")
" </div>"
" </div>"
" </div>"
"</div>"))
Footer
<center>
<a rel="license" href="https://creativecommons.org/licenses/by-sa/3.0/">
<img alt="Creative Commons License" style="border-width:0"
src="https://i.creativecommons.org/l/by-sa/3.0/88x31.png" />
</a>
<br />
<span xmlns:dct="https://purl.org/dc/terms/"
href="https://purl.org/dc/dcmitype/Text" property="dct:title"
rel="dct:type">jao.io</span> by
<a xmlns:cc="https://creativecommons.org/ns#" href="https://jao.io"
property="cc:attributionName" rel="cc:attributionURL">jao</a>
is licensed under a
<a rel="license" href="https://creativecommons.org/licenses/by-sa/3.0/">
Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.
</center>
(setq org-static-blog-page-postamble
(with-temp-buffer
(insert-file-contents "~/.emacs.d/commons.html")
(buffer-string)))
Package
(use-package org-static-blog
:ensure t
:init
(setq org-static-blog-use-preview t
org-static-blog-preview-link-p t
org-static-blog-preview-start "<!-- preview-start -->"
org-static-blog-preview-end "<!-- preview-end -->"
org-static-blog-preview-date-first-p t
org-static-blog-index-length 30
org-static-blog-preview-convert-titles t
org-static-blog-preview-ellipsis "more ..."
org-static-blog-enable-tags t
org-static-blog-tags-file "tags.html"
org-static-blog-rss-file "rss.xml"
org-static-blog-publish-url "https://jao.io/blog/"
org-static-blog-publish-title "programming (and other) musings"
org-static-blog-posts-directory (jao-blog-dir "posts/")
org-static-blog-drafts-directory (jao-blog-dir "pages/")
org-static-blog-publish-directory (jao-blog-dir "blog/")
org-static-blog-rss-extra "" ; "<author>mail@jao.io</author>\n"
org-static-blog-rss-max-entries 30
org-static-blog-rss-excluded-tag "norss"
org-static-blog-enable-tag-rss t
org-export-with-toc nil
org-export-with-section-numbers nil)
:config
(defun jao-org-static-post-path (pf dt)
(cond ((string-match-p "pages/.*\\|in-no-particular-order" pf)
(file-name-nondirectory pf))
((string-match-p "drafts/.*" pf) pf)
((string-match-p "^[[:digit:]]+-.*" pf) pf)
(t (concat (format-time-string "%Y-%m-%d-" dt)
(file-name-nondirectory pf)))))
(advice-add 'org-static-blog-generate-post-path :override
#'jao-org-static-post-path)
:bind (:map org-mode-map (("C-c B" . jao-transient-org-blog))))
Commands
New entries
(defun jao-org-blog-publish-file (fname)
(interactive (list (read-file-name "Publish: "
nil
(buffer-file-name)
t
(buffer-file-name))))
(let ((geiser-active-implementations '(guile))
(geiser-default-implementation 'guile))
(org-static-blog-publish-file fname)))
(defconst jao-org-static-blog--prev-beg
"#+begin_export html\n <!-- preview-start -->\n#+end_export ")
(defconst jao-org-static-blog--prev-end
"#+begin_export html\n <!-- preview-end -->\n#+end_export ")
(defun jao-org-static-blog-create-new-post (&optional draft)
(interactive)
(let* ((title (read-string "Title: "))
(file (replace-regexp-in-string "\s" "-" (downcase title)))
(tags (completing-read-multiple "Tags: " jao-org-blog-tag-names)))
(find-file (expand-file-name (concat file ".org")
(if draft
org-static-blog-drafts-directory
org-static-blog-posts-directory)))
(insert "#+title: " title "\n"
"#+date: " (format-time-string "<%Y-%m-%d %H:%M>") "\n"
"#+filetags: "
(mapconcat #'identity tags " ")
"\n\n")
(when (member "books" tags)
(insert jao-org-static-blog--prev-beg
"\n\n[[https://jao.io/img/" file ".jpg]]\n\n"))
(save-excursion (insert jao-org-static-blog--prev-end "\n"))))
Drafts
(defun jao-org-static-blog-update-date ()
(interactive)
(when (y-or-n-p "Update date? ")
(goto-char (point-min))
(when (re-search-forward "^#\\+date: " nil t)
(let ((kill-whole-line nil)) (kill-line))
(insert (format-time-string "<%Y-%m-%d %H:%M>"))
(save-buffer))))
(defun jao-org-static-blog-create-new-draft ()
(interactive)
(jao-org-static-blog-create-new-post t))
(defun jao-org-static-blog-publish-draft ()
(interactive)
(let* ((from (read-file-name "Post: "
org-static-blog-drafts-directory
nil t))
(to (expand-file-name (file-name-nondirectory from)
org-static-blog-posts-directory)))
(rename-file from to)
(when-let ((b (get-buffer from)))
(kill-buffer b))
(find-file to)
(jao-org-static-blog-update-date)
(when (y-or-n-p "Generate HTML? ")
(jao-org-blog-publish))))
(defun jao-org-static-blog-edit-draft ()
(interactive)
(find-file (read-file-name "Edit: "
org-static-blog-drafts-directory
nil
t)))
Publish
(defun jao-org-blog-publish (&optional force)
(interactive "P")
(let ((geiser-active-implementations '(guile))
(geiser-default-implementation 'guile))
(org-static-blog-publish force)))
(defun jao-org-blog-republish ()
(interactive)
(jao-org-blog-publish t))
Transient
(defun jao-org-static-prev-begin ()
(interactive)
(insert jao-org-static-blog--prev-beg))
(defun jao-org-static-prev-end ()
(interactive)
(insert jao-org-static-blog--prev-end))
(jao-transient-major-mode+ org
["Insert blog snippet"
("s" "preview begin" jao-org-static-prev-begin)
("S" "preview end" jao-org-static-prev-end)
("T" "update date" jao-org-static-blog-update-date)]
["Edit blog"
("n" "create post" jao-org-static-blog-create-new-post)
("d" "create draft" jao-org-static-blog-create-new-draft)
("e" "edit draft" jao-org-static-blog-edit-draft)]
["Publish blog"
("D" "publish draft" jao-org-static-blog-publish-draft)
("f" "publish single file" jao-org-blog-publish-file)
("p" "publish all" jao-org-blog-publish)
("r" "republish" jao-org-blog-republish)])