作者:Justin( j_q_king@foxmail.com

起笔: 2024-09-04 Wed 22:02 | 凝墨: 2024-09-15 Sun 21:32

这个博客运行实现的原理 How this blog published by Emacs

Table of Contents

介绍关于这个博客可能看起来有意思的部分

基础设定

Emacs publish 部分

(setq org-publish-project-alist
      `(
	("site"
         :base-directory ,blog-org-base-directory
         :base-extension "org"
         :recursive nil
         :publishing-directory ,my/publish-directory
         :publishing-function org-html-publish-to-html
	 :html-validation-link nil
	 :html-head ,my-blog-head
	 :htmlized-source t
	 )

        ("posts"
         :base-directory ,(expand-file-name "posts/" blog-org-base-directory)
         :base-extension "org"
         :publishing-directory ,(expand-file-name "posts/" my/publish-directory)
         :publishing-function org-html-publish-to-html
	 :headline-levels 3
	 :html-head ,my-blog-head
	 :html-head-extra ,my-blog-headextra-nav 
	 :html-preamble ,my-blog-preamble
	 :html-postamble ,my-blog-giscus-postamble
	 :exclude-tags ("noexport" "todo")
	 :htmlized-source t
	 :auto-sitemap t
         :sitemap-filename "sitemap_posts.org"
	 :sitemap-title "Posts"
         :sitemap-sort-files anti-chronologically
	 :publishing-function org-html-publish-to-html
	 )

	("topic"
         :base-directory ,(expand-file-name "topic/" blog-org-base-directory)
         :base-extension "org"
         :publishing-directory ,(expand-file-name "topic/" my/publish-directory)
         :publishing-function org-html-publish-to-html
	 :headline-levels 4
	 :htmlized-source t
	 :recursive t
	 
	 :auto-sitemap t
	 
         :sitemap-filename "sitemap_topics.org"
	 :sitemap-title "Topics"
         :sitemap-sort-files anti-chronologically
	 
	 :html-head ,my-blog-head
	 :html-head-extra ,my-blog-headextra-nav
         :html-link-home ""
	 :html-link-up ""
	 :html-preamble ,my-blog-preamble
	 :html-postamble my-org-html-postamble
	 :html-validation-link nil
	 :exclude-tags ("noexport" "todo")
	 )
	
        ("static"
         :base-directory ,blog-org-base-directory
         :base-extension "html\\|css\\|js\\|txt\\|jpg\\|gif\\|png\\|svg\\|pdf"
         :recursive t
         :publishing-directory  ,my/publish-directory
         :publishing-function org-publish-attachment
	 :exclude "^ltximg/\\|/ltximg/"
	 )

        ("Blog"
	 :html-link-home ""
	 :html-link-up ""
	 :html-head-extra ,my-blog-headextra-nav
	 :exclude ".*\\(ltximg\\|~undo-tree~\\).*"
	 :exclude "^ltximg/\\|/ltximg/"
	 :html-validation-link nil
	 :components ("site" "posts" "topic" "static")))
      
      )

推荐阅读详解

年表 blogRecord

生成所有,如何实现按最后修改和最初创建排序, 事实上 org 内有完整两套列表,当点击按钮时会触发 js 控制已被定义 id 的元素 display:none

代码:

(defun create-index-org_2t (org-dir blog-index-file)
  "Create blog index org at BLOG-INDEX-FILE."
  (interactive "D\nFOutput org file: ")
  (let* ((org-files (directory-files-recursively org-dir "\.org$"))
         (output-buffer (find-file blog-index-file))
         (current-year nil)
         (current-month nil)
         (last-modified-content "")
         (created-content ""))
    (with-current-buffer output-buffer
      (erase-buffer)
      (insert "#+title: 年表
#+HTML_LINK_HOME: ./index.html
#+options: num:nil toc:nil
#+begin_export html\n")
      (insert "<div align=\"center\">
  <button onclick=\"showSection('outline-container-last-modified')\">按最后修改排序</button>
  <button onclick=\"showSection('outline-container-created')\">按创建时间排序</button>
</div>\n")      
      (insert "#+end_export\n")
      (insert "* /按最后修改排序的内容/
:PROPERTIES:
:CUSTOM_ID: last-modified
:END:\n")
      ;; 按最后修改时间排序
      (setq org-files
            (sort org-files
                  (lambda (file1 file2)
                    (let* ((time1 (file-attribute-modification-time (file-attributes file1)))
                           (time2 (file-attribute-modification-time (file-attributes file2))))
                      (time-less-p time2 time1)))))
      (dolist (org-file org-files)
        (let* ((date (format-time-string "%Y-%m-%d %H:%M:%S" (file-attribute-modification-time (file-attributes org-file))))
               (title (find-keyword-in-orgfile org-file "TITLE")))
          (if (and title date)
              (let* ((year (substring date 0 4))
                     (month (substring date 5 7))
                     (day (substring date 8 10))
                     (type (file-name-nondirectory (directory-file-name (file-name-directory org-file))))
                     (link (format "[[file:%s][%s-|%s|~ %s]]" org-file day type title)))
                (unless (equal current-year year)
                  (setq current-year year)
                  (setq last-modified-content (concat last-modified-content (format "\n** %s \n" year))))
                (unless (equal current-month month)
                  (setq current-month month)
                  (setq last-modified-content (concat last-modified-content (format "*** %s \n" month))))
                (setq last-modified-content (concat last-modified-content (format "- %s\n" link))))
            (setq last-modified-content (concat last-modified-content (format "- [[file:%s][%s]]\n" org-file (file-name-nondirectory org-file)))))))
      (insert last-modified-content)
      (insert "* 按创建时间排序的内容
:PROPERTIES:
:CUSTOM_ID: created
:END:
")
      (setq org-files
            (sort org-files
                  (lambda (file1 file2)
               	    (let* ((time1 (or (find-keyword-in-orgfile file1 "DATE") "2024-07-31 13:55 Wed"))
                           (time2 (or (find-keyword-in-orgfile file2 "DATE") "2024-07-31 13:55 Wed")))
		      (string> time1 time2)
		      ))))
      (dolist (org-file org-files)
	(let* ((date  (find-keyword-in-orgfile org-file "DATE"))
	       (title (find-keyword-in-orgfile org-file "TITLE")))
          (if (and title date)
              (let* ((year (substring date 0 4))
                     (month (substring date 5 7))
                     (day (substring date 8 10))
                     (type (file-name-nondirectory (directory-file-name (file-name-directory org-file))))
                     (link (format "[[file:%s][%s-|%s|~ %s]]" org-file day type title)))
                (unless (equal current-year year)
                  (setq current-year year)
                  (setq created-content (concat created-content (format "\n** %s \n" year))))
                (unless (equal current-month month)
                  (setq current-month month)
                  (setq created-content (concat created-content (format "*** %s \n" month))))
                (setq created-content (concat created-content (format "- %s\n" link))))
            (setq created-content (concat created-content (format "- [[file:%s][%s]]\n" org-file (file-name-nondirectory org-file)))))))
      (insert created-content)
      (insert "\n#+begin_export html\n</div>
<script>
function showSection(sectionId) {
  document.getElementById('outline-container-last-modified').style.display = 'none';
  document.getElementById('outline-container-created').style.display = 'none';\n")
      (insert "  document.getElementById(sectionId).style.display = 'block';\n")
      (insert "}\n")
      (insert "</script>\n")
      (insert "#+end_export\n")
      (save-buffer)
      (goto-char (point-min))
      (message "Org links generated and saved to %s" blog-index-file))))

它每次在 org-publish 之前运行,便于生成文档之后加入 blog 中

上下篇实现

终于有了这一部分

在 org 里面添加即可

#+PREVIOUS: [[file:将 Windows 截图插入 WSL 中的 Emacs org 中显示.org]]
#+NEXT: [[file:如何使用 LaTeX 完成大物实验报告.org]]

配置函数是

(defun my-org-html-postamble (info)
  (concat (my-html-prev-next-postamble)
	  my-blog-giscus-postamble
            ))

(defun my-html-prev-next-postamble ()
  "Generate custom HTML postamble with navigation links for Org export."
  (let ((previous (org-element-map (org-element-parse-buffer) 'keyword
                    (lambda (k)
                      (when (string= (org-element-property :key k) "PREVIOUS")
                        (org-element-property :value k)))
                   nil t))
        (next (org-element-map (org-element-parse-buffer) 'keyword
                (lambda (k)
                  (when (string= (org-element-property :key k) "NEXT")
                    (org-element-property :value k)))
                nil t))
	)
    (concat
     "<nav class='prev-next-links'>"
     (when previous
       (format "<span class='prev-link'>« 上一篇:%s</span>" 
               (org-export-string-as (format "%s" previous) 'html t)))
     (when next
       (format "<span class='next-link'>下一篇:%s</span>"
               (org-export-string-as (format "%s" next) 'html t)))
     "</nav>"
     )))

之后在里面写上

:html-postamble my-org-html-postamble

然而需要 div 否则评论会把上面吞掉 (之后再加上新代码)

目录随浏览显示

旋转的“背景”图

仅 css 实现,针对元素起效

图片解析 DOT

博客里面的很多风格类似的图片是直接用 DOT 生成插入的,可是原来就发现,如果 PNG 就很没意思清晰度堪忧,而且我一开始就留意到 DOT 支持超链接和 SVG 导出。于是这里第一次成功了 周报/mathInArt249.html

其实主要是改了题头非常简单 :>

\#+BEGIN_SRC dot :file mathInArt249/DOT:20240905182933.svg :results none :exports none  :cmdline -Kdot -Tsvg
digraph development {...}
\#+END_SRC

\#+INCLUDE: "./mathInArt249/DOT:20240905182933.svg" export html

图片解析-截图