org mode 导出 为 latex 时, 如何让 `[[fig]]` link 被强行导出为 `\ref{fig}`, 无论 fig 是否存在?

如题, 我将 org mode 导出为 latex 的习惯不是完整导出, 而是只导出选中的 region 或者 subtree, 比如 [[fig]], fig 定义在我导出的 region 之外的话, 就会是 broken link, 导出后不会有 \ref{fig}. 我目前只好手写 \ref{fig}, 这样在 org mode 中点击是不会跳转链接的. 想问问怎么才能让 [[fig]] 被强行导出为 \ref{fig}?

1 个赞

你需要 org-export-before-processing-hook, 做全文替换. 具体可以看 org manual

我还是选择改代码了, 修改了 my/org-export-resolve-fuzzy-link, 让它查找不到 fuzzy links 时不 signal 而是返回 nil.

(advice-add 'org-export-resolve-fuzzy-link :override #'my/org-export-resolve-fuzzy-link)
(defun my/org-export-resolve-fuzzy-link (link info &rest pseudo-types)
  "Return LINK destination.

INFO is a plist holding contextual information.

Return value can be an object or an element:

- If LINK path matches a target object (i.e. <<path>>) return it.

- If LINK path exactly matches the name or results affiliated keyword
  (i.e. #+NAME: path or #+RESULTS: name) of an element, return that
  element.

- If LINK path exactly matches any headline name, return that
  element.

- Otherwise, throw an error.

PSEUDO-TYPES are pseudo-elements types, i.e., elements defined
specifically in an export backend, that could have a name
affiliated keyword.

Assume LINK type is \"fuzzy\".  White spaces are not
significant."
  (let* ((search-cells (org-export-string-to-search-cell
			(org-element-property :path link)))
	 (link-cache (or (plist-get info :resolve-fuzzy-link-cache)
			 (let ((table (make-hash-table :test #'equal)))
                           ;; Cache all the element search cells.
                           (org-element-map (plist-get info :parse-tree)
		               (append pseudo-types '(target) org-element-all-elements)
	                     (lambda (datum)
		               (dolist (cell (org-export-search-cells datum))
		                 (if (gethash cell table)
                                     (push datum (gethash cell table))
                                   (puthash cell (list datum) table)))))
			   (plist-put info :resolve-fuzzy-link-cache table)
			   table)))
	 (cached (gethash search-cells link-cache 'not-found)))
    (if (not (eq cached 'not-found)) cached
      (let ((matches
             (let (result)
               (dolist (search-cell search-cells)
                 (setq result
                       (nconc
                        result
	                (gethash search-cell link-cache))))
               (delq nil result))))
	(if (null matches)
	  ;; (signal 'org-link-broken (list (org-element-property :path link)))
    nil
  (puthash
    search-cells
    ;; There can be multiple matches for un-typed searches, i.e.,
    ;; for searches not starting with # or *.  In this case,
    ;; prioritize targets and names over headline titles.
    ;; Matching both a name and a target is not valid, and
    ;; therefore undefined.
    (or (cl-some (lambda (datum)
        (and (not (org-element-type-p datum 'headline))
            datum))
            matches)
        (car matches))
    link-cache)
    )
	))))

并且设置:

(setq org-latex-link-with-unknown-path-format "\\ref{%s}")

就可以导出为 \ref{fig} 了.