]> git.vanrenterghem.biz Git - www2.vanrenterghem.biz.git/blobdiff - maak-website.el
Voeg analyse samenvatting Red Rooster OSM toe.
[www2.vanrenterghem.biz.git] / maak-website.el
index f20dc4bd908e053f3b52cb70b6c975c58c24bd69..d878c675e6743a51729f16bb56ef1321ad480cf1 100644 (file)
@@ -1,9 +1,88 @@
+(require 'cl-lib)
+(require 'org)
 (require 'ox-publish)
 (require 'ox-publish)
+(add-to-list 'load-path "~/.emacs.d/elpa/ox-rss-20230408.231")
+(add-to-list 'load-path "~/.emacs.d/elpa/mustache-20230713.514")
+(add-to-list 'load-path "~/.emacs.d/elpa/s-20220902.1511")
+(add-to-list 'load-path "~/.emacs.d/elpa/dash-20230714.723")
+(add-to-list 'load-path "~/.emacs.d/elpa/f-20230823.1159")
+(add-to-list 'load-path "~/.emacs.d/elpa/htmlize-20210825.2150")
+(require 'ox-rss)
+(load "~/.emacs.d/lisp/mustache-html.el")
 
 (setq org-html-doctype "html5")
 (setq org-html-head-include-default-style nil)
 
 (setq org-html-doctype "html5")
 (setq org-html-head-include-default-style nil)
-;(setq org-html-htmlize-output-type 'css) ; default: 'inline-css
+(setq org-html-htmlize-output-type 'css) ; default: 'inline-css
+(setq org-time-stamp-custom-formats '("%A %e %B %Y" . "%A %e %B %Y at %H:%M"))
+(setq org-display-custom-times t)
+(setq org-html-container-element "div") ;; TODO - check
+(setq my-blog-base-folder "~/websites/stage.vanrenterghem.biz")
+(setq my-blog-source-folder "~/websites/stage.vanrenterghem.biz/source")
+(setq my-blog-target-folder "~/websites/stage.vanrenterghem.biz/target")
+(setq my-blog-target-url "https://www.vanrenterghem.biz/posts/")
+(setq my-blog-mustache-folder (file-name-concat my-blog-base-folder "html"))
+(setq my-blog-tags-folder (file-name-concat my-blog-source-folder "tags"))
+(setq my-blog-posts-folder (file-name-concat my-blog-source-folder "posts"))
 
 
+(setq org-export-time-stamp-file nil)
+(setq org-rss-use-entry-url-as-guid nil)
+
+(defun my-org-get-all-filetags ()
+  "Get list of filetags from all org-files in my-blog-posts-folder."
+  (let ((files (directory-files my-blog-posts-folder t nil nil nil))
+        tagslist x)
+    (save-window-excursion
+      (while (setq x (pop files))
+        (set-buffer (find-file-noselect x))
+        (mapc
+         (lambda (y)
+           (let ((tagfiles (assoc y tagslist)))
+             (if tagfiles
+                 (setcdr tagfiles (cons x (cdr tagfiles)))
+               (add-to-list 'tagslist (list y x)))))
+         (my-org-get-filetags)))
+      tagslist)))
+
+(defun my-org-get-filetags ()
+  "Get list of filetags for current buffer"
+  (let ((ftags org-file-tags)
+        x)
+    (mapcar
+     (lambda (x)
+       (org-no-properties x))
+     ftags)))
+
+(defun my-blog-create-tags-files (plist)
+  "Create org files for each tag defined in FILETAGS in posts, storing them in my-blog-tags-folder."
+  (let* ((tagfolder (file-name-concat
+                   (plist-get (cdr (assoc "landing" org-publish-project-alist)) :base-directory)))
+        (postfolder (file-name-concat
+                   (plist-get (cdr (assoc "posts" org-publish-project-alist)) :base-directory)))
+        (relpostfolder (file-relative-name  postfolder tagfolder)))
+    (unless (file-directory-p my-blog-tags-folder) (make-directory my-blog-tags-folder))
+    (with-temp-file (file-name-concat tagfolder "tag-index.org")
+      (insert (concat "#+mustache-template: " (file-name-concat my-blog-mustache-folder "tags-index.mustache") "\n"))
+      (insert (concat "#+TITLE: Blog - All tags\n"))
+      (insert "#+OPTIONS: ^:nil\n") ; do not use underscores as subscript
+      (insert "\n")
+      (dolist (tag (sort (my-org-get-all-filetags) (lambda (x y) (string-lessp (car x) (car y))) ))
+       (insert (concat "- [[file:" (file-name-concat relpostfolder (concat "tag-" (car tag) ".org")) "][" (car tag) "]]\n"))))) 
+  (dolist (tag (my-org-get-all-filetags))
+    (with-temp-file (file-name-concat my-blog-tags-folder (concat "tag-" (car tag) ".org"))
+      (insert (concat "#+mustache-template: " (file-name-concat my-blog-mustache-folder "tags.mustache") "\n"))
+      (insert (concat "#+TITLE: " (car tag) "\n"))
+      (insert "#+OPTIONS: ^:nil\n") ; do not use underscores as subscript
+      (insert "\n")
+      (insert (concat "# " (car tag) "\n\n"))
+      (dolist (tagfile (my-blog-sort-article-list (cdr tag) plist))
+       (let ((relpath (file-relative-name tagfile my-blog-posts-folder)));;not used
+         (message (concat "Processing " tagfile))
+         (insert (concat "- " (format "%s - [[file:%s][%s]]" ;;the date and filename are added after the entry
+                (format-time-string (car org-time-stamp-custom-formats) (org-publish-find-date tagfile plist))
+                relpath
+                (org-publish-find-title tagfile plist))
+                         "\n")))))))
+                                       ;(my-org-publish-sitemap-default-entry tagfile nil plist) "\n")))))))
 
 (defun my-org-publish-sitemap-default-entry (entry style project)
   "My format for site map ENTRY, as a string.
 
 (defun my-org-publish-sitemap-default-entry (entry style project)
   "My format for site map ENTRY, as a string.
@@ -11,7 +90,7 @@ ENTRY is a file name.  STYLE is the style of the sitemap.
 PROJECT is the current project."
   (cond ((not (directory-name-p entry))
         (format "%s - [[file:%s][%s]]" ;;the date and filename are added after the entry
 PROJECT is the current project."
   (cond ((not (directory-name-p entry))
         (format "%s - [[file:%s][%s]]" ;;the date and filename are added after the entry
-                (format-time-string "%e %b %Y" (org-publish-find-date entry project))
+                (format-time-string (car org-time-stamp-custom-formats) (org-publish-find-date entry project))
                 entry
                 (org-publish-find-title entry project)))
        ((eq style 'tree)
                 entry
                 (org-publish-find-title entry project)))
        ((eq style 'tree)
@@ -55,7 +134,7 @@ Either the section between #+BEGIN_PREVIEW and +#END_PREVIEW is used, or the fir
 
 (defun my-blog-sitemap (title list)
   "Generate the sitemap landing page for my blog."
 
 (defun my-blog-sitemap (title list)
   "Generate the sitemap landing page for my blog."
-  (my-plain-publish-sitemap-default title list)
+  (my-plain-publish-sitemap-default title list) ; Create additional sitemap
   (with-temp-buffer
     ;; mangle the parsed list given to us into a plain lisp list of files
     (let* ((filenames (my-blog-parse-sitemap-list list))
   (with-temp-buffer
     ;; mangle the parsed list given to us into a plain lisp list of files
     (let* ((filenames (my-blog-parse-sitemap-list list))
@@ -63,60 +142,95 @@ Either the section between #+BEGIN_PREVIEW and +#END_PREVIEW is used, or the fir
            (articles (my-blog-sort-article-list filenames project-plist)))
       (dolist (file filenames)
        (let* ((abspath (file-name-concat "/home/frederik/websites/stage.vanrenterghem.biz/source/posts" file))
            (articles (my-blog-sort-article-list filenames project-plist)))
       (dolist (file filenames)
        (let* ((abspath (file-name-concat "/home/frederik/websites/stage.vanrenterghem.biz/source/posts" file))
-               (relpath (file-relative-name abspath "/home/frederik/websites/stage.vanrenterghem.biz/"))
+               (relpath (file-relative-name abspath "/home/frederik/websites/stage.vanrenterghem.biz/source/posts/"))
                (title (org-publish-find-title file project-plist))
                (title (org-publish-find-title file project-plist))
-               (date (format-time-string (car org-time-stamp-formats) (org-publish-find-date file project-plist)))
+               (date (format-time-string (cdr org-time-stamp-custom-formats) (org-publish-find-date file project-plist)))
                (preview (my-blog-get-preview abspath))
               )
           ;; insert a horizontal line before every post, kill the first one
           ;; before saving
                (preview (my-blog-get-preview abspath))
               )
           ;; insert a horizontal line before every post, kill the first one
           ;; before saving
-          (insert "-----\n")
           (insert (concat "* [[file:" relpath "][" title "]]\n"))
           ;; add properties for `ox-rss.el' here
           (insert (concat "* [[file:" relpath "][" title "]]\n"))
           ;; add properties for `ox-rss.el' here
-                                       ;(let ((rss-permalink (concat (file-name-sans-extension relpath) ".html"))
-                                       ;      (rss-pubdate date))
-                                       ;  (org-set-property "RSS_PERMALINK" rss-permalink)
-                                       ;  (org-set-property "PUBDATE" rss-pubdate))
+         (let ((rss-permalink (concat (file-name-sans-extension relpath) ".html"))
+               (rss-pubdate (format-time-string (cdr org-time-stamp-formats) (org-publish-find-date file project-plist))))
+           (org-mode)
+           (org-set-property "HTML_CONTAINER_CLASS" "card mb-2") ;Bootstrap margin border 2
+           (org-set-property "HTML_HEADLINE_CLASS" "card-header card-title border-bottom-0 fs-5 fw-bold text-decoration-none")
+           (org-set-property "RSS_PERMALINK" rss-permalink)
+           (org-set-property "PUBDATE" rss-pubdate)
+           (org-set-property "RSS_TITLE" title))
           ;; insert the date, preview, & read more link
           ;; insert the date, preview, & read more link
+         (insert "#+ATTR_HTML: :class card-header\n")
           (insert (concat "Published: " date "\n\n"))
           (insert (concat "Published: " date "\n\n"))
+         (insert "#+BEGIN_export html\n")
+         (insert "<section class=\"card-body\">\n")
+         (insert "#+END_export\n")
          (insert preview)
                                        ;(insert (concat "#+INCLUDE: \"" relpath "\" :only-contents t :lines \"1-10\"\n"))
          (insert preview)
                                        ;(insert (concat "#+INCLUDE: \"" relpath "\" :only-contents t :lines \"1-10\"\n"))
-          (insert "\n")
-          (insert (concat "[[file:" relpath "][Read More...]]\n"))))
+         (insert "\n")
+          (insert (concat "[[file:" relpath "][Read More...]]\n"))
+         (insert "#+BEGIN_export html\n")
+         (insert "</section> <!-- END CARD-BODY-->\n")
+         (insert "#+END_export\n")
+         ))
       ;; kill the first hrule to make this look OK
       ;; kill the first hrule to make this look OK
-      (goto-char (point-min))
-      (let ((kill-whole-line t)) (kill-line))
+      ;(goto-char (point-min))
+      ;(let ((kill-whole-line t)) (kill-line))
       ;; insert a title and save
       (insert "#+OPTIONS: title:nil\n")
       ;; insert a title and save
       (insert "#+OPTIONS: title:nil\n")
-      (insert "#+TITLE: Blog\n")
+      (insert "#+TITLE: Frederik Vanrenterghem's blog\n")
       (insert "#+AUTHOR: Frederik Vanrenterghem\n")
       (insert "#+EMAIL: frederik@vanrenterghem.biz\n")
       (insert "#+OPTIONS: ^:nil\n") ; do not use underscores as subscript
       (insert "#+AUTHOR: Frederik Vanrenterghem\n")
       (insert "#+EMAIL: frederik@vanrenterghem.biz\n")
       (insert "#+OPTIONS: ^:nil\n") ; do not use underscores as subscript
-      (insert "#+mustache-template: ~/websites/stage.vanrenterghem.biz/html/post-index.mustache\n")
+      (insert (concat "#+mustache-template: " (file-name-concat my-blog-mustache-folder "post-index.mustache") "\n"))
       (insert "\n")
       (buffer-string))))
 
 (defun my-plain-publish-sitemap-default (title list)
       (insert "\n")
       (buffer-string))))
 
 (defun my-plain-publish-sitemap-default (title list)
-  "Default site map, as a string.
+  "Create a simple site map, as a string.
 TITLE is the title of the site map.  LIST is an internal
 representation for the files to include, as returned by
 TITLE is the title of the site map.  LIST is an internal
 representation for the files to include, as returned by
-`org-list-to-lisp'.  PROJECT is the current project."
+`org-list-to-lisp'."
   (with-temp-file "~/websites/stage.vanrenterghem.biz/source/sitemap.org"
   (with-temp-file "~/websites/stage.vanrenterghem.biz/source/sitemap.org"
-    (insert "#+OPTIONS: ^:nil\n") ; do not use underscores as subscript
-    (insert (concat "#+TITLE: " title "\n\n"))
-    (insert (org-list-to-org list))))
+    (let* ((filenames (my-blog-parse-sitemap-list list))
+           (project-plist (assoc "posts" org-publish-project-alist))
+           (articles (my-blog-sort-article-list filenames project-plist)))
+      (dolist (file filenames)
+       (let* ((abspath (file-name-concat "/home/frederik/websites/stage.vanrenterghem.biz/source/posts" file))
+               (relpath (file-relative-name abspath "/home/frederik/websites/stage.vanrenterghem.biz/source/"))
+               (title (org-publish-find-title file project-plist))
+               (date (format-time-string (car org-time-stamp-custom-formats) (org-publish-find-date file project-plist))))
+         (insert (concat "* " date " - [[file:" relpath "][" title "]]\n"))))
+      (goto-char (point-min))
+      (insert "#+OPTIONS: ^:nil\n")))) ; do not use underscores as subscript
 
 
+(defun my-blog-cleanup-sitemaps (plist)
+  "Clean up temporary files created in the process of publishing"
+  ;; Create a body-only version of the tags index. Needs absolute path to posts folder.
+  (with-temp-file (file-name-concat
+                  (plist-get (cdr (assoc "landing" org-publish-project-alist)) :publishing-directory)
+                  "tag-index-body.html")
+    (insert-file-contents (file-name-concat
+                          (plist-get (cdr (assoc "landing" org-publish-project-alist)) :base-directory)
+                          "tag-index.org"))
+    (org-export-to-buffer 'mustache-html (current-buffer) nil nil nil t nil)
+    (replace-string "href=\"posts" "href=\"/posts"))
+  (delete-file (file-name-concat my-blog-source-folder "sitemap.org"))
+  (delete-file (file-name-concat my-blog-posts-folder "sitemap.org"))
+  (delete-file (file-name-concat my-blog-posts-folder "sitemap.org~")))
+  
 (setq org-publish-project-alist
 (setq org-publish-project-alist
-      '(("landing"
-         :base-directory "~/websites/stage.vanrenterghem.biz/source/"
+      `(("landing"
+         :base-directory ,my-blog-source-folder
          :base-extension "org"
          :base-extension "org"
-        :include ("posts/sitemap.org")
-         :publishing-directory "~/websites/stage.vanrenterghem.biz/target"
+         :publishing-directory ,my-blog-target-folder
         :publishing-function org-mustache-html-publish-to-html
         :publishing-function org-mustache-html-publish-to-html
-        :mustache-template "~/websites/stage.vanrenterghem.biz/html/landing.mustache"
-         :headline-levels 3
+        :mustache-template ,(file-name-concat my-blog-mustache-folder "landing.mustache")
+         :headline-levels 2
          :section-numbers nil
          :with-toc nil
          :section-numbers nil
          :with-toc nil
+        :with-title nil
+        :html-content-class nil
         :html-head-include-default-style nil
          :html-head nil
         :html-divs nil
         :html-head-include-default-style nil
          :html-head nil
         :html-divs nil
@@ -125,12 +239,13 @@ representation for the files to include, as returned by
         )
 
        ("posts"
         )
 
        ("posts"
-         :base-directory "~/websites/stage.vanrenterghem.biz/source/posts/"
+         :base-directory ,my-blog-posts-folder
          :base-extension "org"
          :base-extension "org"
-         :publishing-directory "~/websites/stage.vanrenterghem.biz/target/posts"
+         :publishing-directory ,(file-name-concat my-blog-target-folder "posts")
          :publishing-function org-mustache-html-publish-to-html
          :publishing-function org-mustache-html-publish-to-html
-        :mustache-template "~/websites/stage.vanrenterghem.biz/html/post.mustache"
-         :exclude "assets*\\|index.org" ;"assets*\\|sitemap.org\\|index.org" ;; regexp
+        :mustache-template ,(file-name-concat my-blog-mustache-folder "post.mustache")
+        :preparation-function my-blog-create-tags-files
+         :exclude "html*\\|assets*\\|index.org\\|sitemap.org" ;"assets*\\|sitemap.org\\|index.org" ;; regexp
         :html-content-class nil
          :section-numbers nil
          :with-toc nil
         :html-content-class nil
          :section-numbers nil
          :with-toc nil
@@ -145,17 +260,53 @@ representation for the files to include, as returned by
         :html-postamble nil
         :sitemap-sort-folders ignore-errors
         :sitemap-function my-blog-sitemap
         :html-postamble nil
         :sitemap-sort-folders ignore-errors
         :sitemap-function my-blog-sitemap
-         ;:sitemap-function org-publish-sitemap-default
-        ;:sitemap-format-entry my-org-publish-sitemap-default-entry
         :sitemap-sort-files anti-chronologically
         :sitemap-filename "sitemap.org"
         )
 
         :sitemap-sort-files anti-chronologically
         :sitemap-filename "sitemap.org"
         )
 
+       ("tags"
+         :base-directory ,(file-name-concat my-blog-source-folder "tags")
+         :base-extension "org"
+         :publishing-directory ,(file-name-concat my-blog-target-folder "posts")
+         :publishing-function org-mustache-html-publish-to-html
+        :mustache-template ,(file-name-concat my-blog-mustache-folder "tags.mustache")
+        :html-content-class nil
+         :section-numbers nil
+         :with-toc nil
+        :with-title nil
+        :html-head-include-default-style nil
+         :html-head nil
+        :html-divs nil
+        :recursive nil
+        :auto-sitemap nil
+        :html-preamble nil
+        :html-postamble nil
+        )
+
         ("assets"
         ("assets"
-         :base-directory "~/websites/stage.vanrenterghem.biz/source/assets/"
+         :base-directory ,(file-name-concat my-blog-source-folder "assets")
          :base-extension any
         :recursive t
          :base-extension any
         :recursive t
-         :publishing-directory "~/websites/stage.vanrenterghem.biz/target/assets/"
-         :publishing-function org-publish-attachment)
+         :publishing-directory ,(file-name-concat my-blog-target-folder "assets")
+         :publishing-function org-publish-attachment
+        :completion-function my-blog-cleanup-sitemaps
+        )
+       
+       ("rss"
+         :base-directory ,my-blog-posts-folder
+         :base-extension "org"
+         :publishing-directory ,(file-name-concat my-blog-target-folder "posts")
+         :publishing-function org-rss-publish-to-rss
+         :with-author t
+        :title "Frederik Vanrenterghem's blog"
+         :html-link-home ,my-blog-target-url
+         :html-link-use-abs-url t
+        :section-numbers nil
+         :exclude ".*"
+         :include ("sitemap.org")
+         :table-of-contents nil
+         )
+       
+        ("website" :components ("posts" "rss" "tags" "landing" "assets"))))
 
 
-        ("website" :components ("posts" "landing" "assets"))))
+(org-publish-initialize-cache "website")