这个博客运行实现的原理 How this blog published by Emacs
介绍关于这个博客可能看起来有意思的部分
基础设定
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
目录随浏览显示
通过 js 参考其它网站实现
图片解析 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
图片解析-截图
请看 我如何插图的:一个函数
Your next stop draft/criticize&reflection.html