标题锚唯一
2023年11月30日 2024年1月25日
ox-hugo导出时关于标题锚的设定
-
变量
org-hugo-anchor-functions
存放若干个函数, 优先级从高到低, 最先返回不为nil, 用作标题锚函数 对应属性配置 org-hugo-get-page-or-bundle-name 导出文件名 :EXPORT_FILE_NAME org-hugo-get-custom-id 自定义ID :CUSTOM_ID org-hugo-get-heading-slug 标题名称 org-hugo-get-md5 计算标题名称md5 org-hugo-get-id 分配ID :ID -
ID
之前使用org-roam实现双链笔记本时, 为部分标题添加了ID, 这个是不可能普及的 -
自定义ID
需手动配置 -
标题名称
当前标题的处理方式, 存在标题重名问题 -
md5
和标题名称一样的问题, 还不直观 -
导出文件名
注意: 这个的优先级最高, 因为会使用到文章锚
Hugo对Markdown文件标题ID的处理
-
当标题后没有跟锚时, 会对重名标题编号
## Reference ## Reference ## Reference
当id不同时, 在Hugo中可以设置不同锚
1<h2 id="reference">Reference</h2> 2<h2 id="reference-1">Reference</h2> 3<h2 id="reference-2">Reference</h2>
-
如果标题后有锚, 标题id为锚移除"#“的内容
允许重名## Reference A {#foo}
1<h2 id="foo">Reference A</h2>
对重名id编号
-
如果Markdown文件中没有锚, 这个就不需要额外处理
-
如果打算额外处理, 而文章目录依据文章正文生成, 修改Markdown文件好过修改html
-
如果打算修改Markdown, 即自己找重名标题, 不如ox-hugo导出时所有标题的锚都相同: 全删即可
-
即, ox-hugo为所有标题生成相同的锚, 或者不生成锚; 后者需要修改ox-hugo源码
影响
部分博文里包含其他博文+标题链接, 这些标题有ID, 且基本不会存在重名的情况
因此, 如让ox-hugo为所有标题生成相同的锚, 不包括文章标题, 即不使用ID作为锚, 就不用修改双链跳转
解决方案
让ox-hugo为所有标题生成相同的锚
设置 org-hugo-anchor-functions
, 函数优先级如下
org-hugo-get-page-or-bundle-name
org-hugo-get-custom-id
且仅有这两个函数
修改导出之后的文本内容
- 注释之前的定义
- my/ox-hugo-export-subtree
- my/ox-hugo-export-all-subtrees
- my/ox-hugo-export-subtree
- 重新定义: 调用修改文本函数
- 实现修改文本函数
修改文本
移除标题锚
1(defun my/remove-anchor-file (file) 2 (interactive) 3 (with-current-buffer (find-file-noselect file) 4 (beginning-of-buffer) 5 (replace-string "{#}" "") 6 (save-buffer) 7 (kill-buffer) 8 ) 9 )
移除给定子树标题锚
1(defun my/remove-anchor-file-name (export-name) 2 (interactive) 3 (my/remove-anchor-file (concat (my/subtree-path-str export-name) ".md")) 4 )
移除文件内所有子树标题锚
1(defun my/remove-anchor-pack () 2 (interactive) 3 (beginning-of-buffer) 4 (while (re-search-forward (rx ":" "EXPORT_FILE_NAME" ": " (group (0+ (not "\n"))) "\n") nil t) 5 (my/remove-anchor-file-name (string-join (mapcar #'string (match-string 1)))) 6 ) 7 )
导出子树
光标所在子树
1(defun my/ox-hugo-export-subtree () 2 (interactive) 3 (save-excursion 4 (outline-next-heading) 5 (when (re-search-backward (rx ":" "EXPORT_FILE_NAME" ": " (group (0+ (not "\n"))) "\n") nil t) 6 (let* ((export-name (string-join (mapcar #'string (match-string 1)))) 7 (subtree (my/copy-org-subtree)) 8 (options (my/copy-org-options)) 9 (weight (my/compute-weight)) 10 (slotlist '()) 11 (slotlist (my/compute-subtree-path export-name)) 12 (slot) 13 (section) 14 (cur-level)) 15 (with-temp-buffer 16 (org-mode) 17 (insert options) 18 (insert subtree) 19 (my/delete-timestamp-link) 20 (my/replace-ue-project-file-link) 21 (my/replace-ue-engine-file-link) 22 (my/replace-roam-link) 23 (pop slotlist) 24 (setq slotlist (reverse slotlist)) 25 (pop slotlist) 26 (setq slotlist (reverse slotlist)) 27 (dolist (item slotlist) 28 (setq slot (concat slot "/" item)) 29 ) 30 (beginning-of-buffer) 31 (when (re-search-forward (rx "+" "HUGO_SECTION" ": " (group (0+ (not "\n")))) nil t) 32 (setq section (string-join (mapcar #'string (match-string 1)))) 33 (replace-match (format (concat "+" "HUGO_SECTION" ": %s") (concat section slot))) 34 ) 35 (beginning-of-buffer) 36 (when (re-search-forward (rx "EXPORT_HUGO_WEIGHT" ": " (group (0+ (not "\n")))) nil t) 37 (replace-match (format (concat "EXPORT_HUGO_WEIGHT" ": %s") weight)) 38 ) 39 (beginning-of-buffer) 40 (outline-next-heading) 41 (setq cur-level (funcall outline-level)) 42 (while (/= 1 cur-level) 43 (org-shiftmetaleft) 44 (setq cur-level (funcall outline-level)) 45 ) 46 (org-hugo-export-wim-to-md) 47 (my/amend-pic-link-file-name export-name) 48 (my/remove-anchor-file-name export-name) 49 ) 50 ) 51 ) 52 ) 53 ) 54(global-set-key (kbd "C-c h s") 'my/ox-hugo-export-subtree)
文件内所有子树
1(defun my/ox-hugo-export-all-subtrees () 2 (interactive) 3 (save-excursion 4 (let ((buf-content (buffer-string))) 5 (with-temp-buffer 6 (org-mode) 7 (insert buf-content) 8 (my/delete-timestamp-link) 9 (my/replace-ue-project-file-link) 10 (my/replace-ue-engine-file-link) 11 (my/replace-roam-link) 12 (org-hugo-export-wim-to-md :all-subtrees) 13 (my/amend-pic-link-pack) 14 (my/remove-anchor-pack) 15 ) 16 ) 17 ) 18 ) 19(global-set-key (kbd "C-c h a") 'my/ox-hugo-export-all-subtrees)
遗留问题
- 如果有时间和精力, 建议部分标题使用Roam ID作为锚
Hugo对Markdown文件的要求
Markdown文件中的标题级别建议为2-4. ox-hugo导出时, 会将大于4的标题变作列表
修改ox-hugo源码思路
-
org-hugo–get-anchor函数会读取org-hugo-anchor-functions
-
org-hugo-heading会调用org-hugo–get-anchor来为标题添加锚, 将
anchor
设置为空即可实现
不建议这么做, ox-hugo的实现可能会改变, 而给出思路仅作为解决问题能力的锻炼
便签
- |
---|
ox-hugo锚 |