#!/usr/bin/emacs --script ;; Lots of code were taken from: ;; - https://gitlab.com/to1ne/blog/-/blob/master/elisp/publish.el ;; - https://github.com/dmacvicar/site.org/blob/master/publish.el ;; I don't want this script, especially package, to mess my Emacs directory. (setq user-emacs-directory (expand-file-name ".cache/" default-directory)) (load-file (expand-file-name "elisp/no-littering.el" default-directory)) (setq package-user-dir (with-no-warnings (no-littering-expand-var-file-name "package/"))) (require 'package) (package-initialize) (unless package-archive-contents (add-to-list 'package-archives '("org" . "https://orgmode.org/elpa/") t) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) (package-refresh-contents)) (dolist (pkg '(org-plus-contrib htmlize)) (unless (package-installed-p pkg) (package-install pkg))) (require 'cl-lib) (require 'sh-script) (require 'ox) (require 'ox-publish) (require 'ox-rss) ;; Taken from doom-emacs (defmacro c/pushnew! (place &rest values) "Push VALUES sequentially into PLACE, if they aren't already present. This is a variadic `cl-pushnew'." (let ((var (make-symbol "result"))) `(dolist (,var (list ,@values) (with-no-warnings ,place)) (cl-pushnew ,var ,place :test #'equal)))) ;; Some Quality of Life link abbrevations. (c/pushnew! org-link-abbrev-alist '("carbs-pkg" . "https://git.sr.ht/~carbslinux/repository/tree/master/item/%s") '("srht" . "https://git.sr.ht/%s") '("ml" . "https://lists.sr.ht/~carbslinux/%s") '("mlto" . "mailto:~carbslinux/%s@lists.sr.ht") '("github" . "https://github.com/%s")) (defvar carbs--src-directory (expand-file-name "src/" default-directory) "Directory for most of the static webpage content.") (defvar carbs--publish-directory (expand-file-name "docs/" default-directory) "Root directory of the published website.") (defvar carbs--news-directory (expand-file-name "news/" default-directory) "Directory for news posts.") (defvar carbs--blog-directory (expand-file-name "blog/" default-directory) "Directory for blog posts.") (defvar carbs--template-directory (expand-file-name "templates/" default-directory) "Directory for all types of templates") (defun carbs--insert-template (file) "Insert FILE from `carbs--template-directory'." (with-temp-buffer (insert-file-contents (expand-file-name file carbs--template-directory)) (buffer-string))) (defun carbs/org-html-publish-to-html (plist filename pub-dir) "Wrapper function that adds publishing date as a subtitle. PLIST contains the properties, FILENAME the source file and PUB-DIR the output directory." (let ((project (cons 'rw plist))) (plist-put plist :subtitle (carbs/format-date-subtitle filename project)) (org-html-publish-to-html plist filename pub-dir))) (defun carbs/org-html-publish-blog-index (plist filename pub-dir) "Wrapper function to publish only the index file to html. PLIST contains the properties, FILENAME the source file and PUB-DIR the output directory." (if (equal "index.org" (file-name-nondirectory filename)) (org-html-publish-to-html plist filename pub-dir))) (defun carbs/format-rss-feed-entry (entry style project) "Format ENTRY for the RSS feed. ENTRY is a file name. STYLE is either 'list' or 'tree'. PROJECT is the current project." (cond ((not (directory-name-p entry)) (let* ((file (org-publish--expand-file-name entry project)) (title (org-publish-find-title entry project)) (date (format-time-string "%Y-%m-%d" (org-publish-find-date entry project))) (link (concat (file-name-sans-extension entry) ".html"))) (with-temp-buffer (insert (format "* %s\n" title)) (org-set-property "RSS_PERMALINK" link) (org-set-property "PUBDATE" date) (insert-file-contents file) (buffer-string)))) ((eq style 'tree) ;; Return only last subdir. (file-name-nondirectory (directory-file-name entry))) (t entry))) (defun carbs/format-rss-feed (title list) "Generate RSS feed, as a string. TITLE is the title of the RSS feed. LIST is an internal representation for the files to include, as returned by `org-list-to-lisp'. PROJECT is the current project." (concat "#+TITLE: " title "\n" "#+DESCRIPTION: a simple Linux distribution\n\n" (org-list-to-subtree list 1 '(:icount "" :istart "")))) (defun carbs/org-rss-publish-to-rss (plist filename pub-dir) "Publish RSS with PLIST, only when FILENAME is 'rss.org'. PUB-DIR is when the output will be placed." (org-rss-publish-to-rss plist filename pub-dir)) (defun carbs/format-date-subtitle (file project) "Format the date found in FILE of PROJECT." (format-time-string "posted on %b %d, %Y" (org-publish-find-date file project))) (defun carbs--pre/postamble-format (type) "Return the content for the pre/postamble of TYPE." `(("en" ,(carbs--insert-template (format "%s.html" type))))) (defun carbs/org-publish-sitemap (title list) "Generate sitemap as a string, having TITLE. LIST is an internal representation for the files to include, as returned by `org-list-to-lisp'." (let ((filtered-list (cl-remove-if (lambda (x) (and (sequencep x) (null (car x)))) list))) (concat (carbs--insert-template "blog.org") (org-list-to-org filtered-list) "\n"))) (defun carbs/org-publish-latest-blog (title list) "Generate sitemap as a string, having TITLE. LIST is an internal representation for the files to include, as returned by `org-list-to-lisp'." (let* ((filtered-list (cl-remove-if (lambda (x) (and (sequencep x) (null (car x)))) list)) (latest-posts (seq-subseq filtered-list 0 (min (length filtered-list) 4)))) (concat (org-list-to-org latest-posts) "\n"))) (defun carbs/org-publish-latest-blog-entry (entry style project) "Format for sitemap ENTRY, as a string. ENTRY is a file name. STYLE is the style of the sitemap. PROJECT is the current project." (unless (equal entry "404.org") (format "%s - [[file:%s][%s]]" (format-time-string "%b %d, %Y" (org-publish-find-date entry project)) entry (org-publish-find-title entry project)))) (defun carbs/org-publish-sitemap-entry (entry style project) "Format for sitemap ENTRY, as a string. ENTRY is a file name. STYLE is the style of the sitemap. PROJECT is the current project." (unless (equal entry "404.org") (format "[[file:%s][%s]] /%s/" entry (org-publish-find-title entry project) (carbs/format-date-subtitle entry project)))) (defun carbs/org-publish-news (title list) "Generate sitemap as a string, having TITLE. LIST is an internal representation for the files to include, as returned by `org-list-to-lisp'." (let ((filtered-list (cl-remove-if (lambda (x) (and (sequencep x) (null (car x)))) list))) (concat "#+TITLE: News Index\n\n" (org-list-to-subtree filtered-list 1 '(:istart "" :icount "")) "\n"))) (defun carbs/org-publish-news-latest (title list) "Generate sitemap as a string, having TITLE. LIST is an internal representation for the files to include, as returned by `org-list-to-lisp'." (let* ((filtered-list (cl-remove-if (lambda (x) (and (sequencep x) (null (car x)))) list)) (latest-posts (seq-subseq filtered-list 0 (min (length filtered-list) 6)))) (concat (org-list-to-subtree latest-posts 1 '(:istart "" :icount "")) "\n"))) (defun carbs/org-publish-news-entry (entry style project) "Format for sitemap ENTRY, as a string. ENTRY is a file name. STYLE is the style of the sitemap. PROJECT is the current project." (cond ((not (directory-name-p entry)) (let* ((file (org-publish--expand-file-name entry project)) (date (format-time-string "%b %d, %Y" (org-publish-find-date entry project))) (link (concat (file-name-sans-extension entry) ".html"))) (with-temp-buffer (insert (format "* [[file:%s][%s]]\n" link date)) (insert-file-contents file) (buffer-string)))) ((eq style 'tree) ;; Return only last subdir. (file-name-nondirectory (directory-file-name entry))) (t entry))) (setq user-full-name "Cem Keylan" user-mail-address "root@carbslinux.org" org-publish-timestamp-directory (with-no-warnings (no-littering-expand-var-file-name "timestamps/")) org-html-doctype "html5" org-html-head (concat "\n" "") org-html-head-include-scripts nil org-html-metadata-timestamp-format "%Y-%m-%d" org-html-head-include-default-style nil org-html-html5-fancy t org-html-htmlize-output-type 'css org-export-with-toc nil org-export-with-section-numbers nil org-publish-project-alist (list (list "news" :author "" :base-directory carbs--news-directory :html-preamble t :html-postamble t :html-preamble-format (carbs--pre/postamble-format 'preamble) :html-postamble-format (carbs--pre/postamble-format 'postamble) :publishing-directory (expand-file-name "news/" carbs--publish-directory) :publishing-function '(org-html-publish-to-html org-ascii-publish-to-ascii) :exclude (regexp-opt '("index.org" "news.org" "latest-news.org")) :auto-sitemap t :sitemap-filename "index.org" :sitemap-style 'list :sitemap-title "Carbs Linux news" :sitemap-sort-files 'anti-chronologically :sitemap-function 'carbs/org-publish-news :sitemap-format-entry 'carbs/org-publish-news-entry) (list "news-rss-generate" :base-directory carbs--news-directory :publishing-directory carbs--publish-directory :publishing-function 'ignore :exclude (regexp-opt '("index.org" "news.org" "latest-news.org")) :html-link-home "https://carbslinux.org/news" :auto-sitemap t :sitemap-filename "news.org" :sitemap-style 'list :sitemap-title "Carbs Linux news" :sitemap-sort-files 'anti-chronologically :sitemap-function 'carbs/format-rss-feed :sitemap-format-entry 'carbs/format-rss-feed-entry) (list "latest-news" :base-directory carbs--news-directory :publishing-directory carbs--publish-directory :publishing-function 'ignore :exclude (regexp-opt '("index.org" "news.org" "latest-news.org")) :auto-sitemap t :sitemap-filename "latest-news.org" :sitemap-style 'list :sitemap-title "Carbs Linux news" :sitemap-sort-files 'anti-chronologically :sitemap-function 'carbs/org-publish-news-latest :sitemap-format-entry 'carbs/org-publish-news-entry) (list "news-rss-publish" :base-directory carbs--news-directory :exclude "." :include '("news.org") :rss-extension "xml" :recursive t :html-link-home "https://carbslinux.org/news" :publishing-directory carbs--publish-directory :publishing-function 'carbs/org-rss-publish-to-rss) (list "blog-latest" :base-directory carbs--blog-directory :publishing-directory carbs--publish-directory :publishing-function 'ignore :exclude (regexp-opt '("index.org" "rss.org" "latest-blog.org")) :auto-sitemap t :sitemap-filename "latest-blog.org" :sitemap-style 'list :sitemap-sort-files 'anti-chronologically :sitemap-function 'carbs/org-publish-latest-blog :sitemap-format-entry 'carbs/org-publish-latest-blog-entry) (list "home" :base-directory carbs--src-directory :html-preamble t :html-postamble t :html-preamble-format (carbs--pre/postamble-format 'preamble) :html-postamble-format (carbs--pre/postamble-format 'postamble) :publishing-directory carbs--publish-directory :publishing-function 'org-html-publish-to-html) (list "blog-index-publish" :base-directory carbs--blog-directory :publishing-directory (expand-file-name "blog/" carbs--publish-directory) :publishing-function 'carbs/org-html-publish-blog-index :html-preamble t :html-postamble t :html-preamble-format (carbs--pre/postamble-format 'preamble) :html-postamble-format (carbs--pre/postamble-format 'postamble) :html-link-org-files-as-html t :exclude (regexp-opt '("rss.org" "index.org" "latest-blog.org")) :auto-sitemap t :sitemap-filename "index.org" :sitemap-style 'list :sitemap-title "Carbs Linux blog" :sitemap-sort-files 'anti-chronologically :sitemap-function 'carbs/org-publish-sitemap :sitemap-format-entry 'carbs/org-publish-sitemap-entry) (list "blog" :base-directory carbs--blog-directory :publishing-directory (expand-file-name "blog/" carbs--publish-directory) :publishing-function 'carbs/org-html-publish-to-html :html-preamble t :html-postamble t :html-preamble-format (carbs--pre/postamble-format 'preamble) :html-postamble-format (carbs--pre/postamble-format 'postamble) :exclude (regexp-opt '("rss.org" "index.org" "latest-blog.org")) :html-link-org-files-as-html t) (list "blog-generate-rss-sitemap" :base-extension "org" :base-directory carbs--blog-directory :html-link-home "https://carbslinux.org/blog" :exclude (regexp-opt '("rss.org" "index.org" "latest-blog.org")) :publishing-function 'ignore :publishing-directory (expand-file-name "blog/" carbs--publish-directory) :rss-extension "xml" :auto-sitemap t :html-link-org-files-as-html t :sitemap-filename "rss.org" :sitemap-title "Carbs Linux blog" :sitemap-style 'list :sitemap-sort-files 'anti-chronologically :sitemap-function 'carbs/format-rss-feed :sitemap-format-entry 'carbs/format-rss-feed-entry) (list "blog-publish-rss-sitemap" :base-directory carbs--blog-directory :rss-extension "xml" :recursive t :exclude "." :include '("rss.org") :publishing-directory carbs--publish-directory :publishing-function 'carbs/org-rss-publish-to-rss :html-link-home "https://carbslinux.org/blog" :html-link-use-abs-url t) (list "plaintext" :author "" :base-directory carbs--src-directory :publishing-directory carbs--publish-directory :publishing-function 'org-ascii-publish-to-ascii :base-extension "org" :exclude (regexp-opt '("rss.org" "latest-blog.org")) :recursive t) (list "blog-txt" :base-directory carbs--blog-directory :base-extension "org" :exclude (regexp-opt '("rss.org" "latest-blog.org")) :publishing-directory (expand-file-name "blog/" carbs--publish-directory) :publishing-function 'org-ascii-publish-to-ascii))) (org-publish-all)