代码更新标签问题

想在org mode内实现更新图片 标签和引用 写了以下代码

    (defun update_fig ()
      (interactive)
      (save-excursion
        (goto-char (point-min))
        (let ((count 1))
          (while (re-search-forward "fig\\([0-9]+\\)" nil t)
            (setq match (match-string 0))
            (save-excursion
              (replace-match (format "%d" count) nil nil nil 1)
              (while (search-forward match nil t)
                (replace-match (format "%s%d" "fig" count) nil nil nil nil)))
            (setq count (1+ count))
            ))))

即想实现 如下功能

fig4 fig3 fig1 fig4 —> fig1 fig2 fig3 fig1

但是得到的结果是

fig1 fig2 fig3 fig4

但是如果把 replace-match 一行改为 (replace-match (format "%d" count) nil nil nil nil)

会得到

fig1 fig2 fig3 1

但是我需要在1 前面加入 “fig” 字符串

不知道问题出现在哪,谢谢大家

什么意思?

这有什么规律吗?

一般写latex 文档时 有用 \label{fig2} 然后在其它的地方又用到了 \cite{fig2}, 这其中可能出现其他的一些标签。\label{fig3} \label{fig4} 等等,所以我想让它们通过这个函数更新。

最后生成的标签是以数字排序,并且同时更新其引用

就是将无序的标签更新成有序的标签,如果有几个标签一样,则同时更新这几个标签

之前没认真看,以为只是翻转一个序列。还纳闷什么奇怪的需求。

你这个方法是有问题的。一旦 count 累加到跟已经存在的数字相同时,就产生冲突了:

n: count
m: match

n   m->n   before    after
--- ------ --------- -------
1   4->1   4 3 1 4   1 3 1 1
2   3->2     3 1 1     2 1 1
3   1->3       1 1       3 3
4   3->4         3         4
----------------------------
          final ---> 1 2 3 4

我明白了,谢谢

我按照你的思路做了些修改,增加了一次循环:

(save-excursion
  (goto-char (point-min))
  (let ((count 1)
        (unique "exjNS0EVjWd6uY6HqioxveNP4gJUr8TL"))
    ;; 临时标签
    (while (re-search-forward "fig\\([0-9]+\\)" nil t)
      (setq match (match-string 0))
      (save-excursion
        (replace-match (format "%s%d" unique count) nil nil nil nil)
        (while (search-forward match nil t)
          (replace-match (format "%s%d" unique count) nil nil nil nil)))
      (setq count (1+ count)))

    ;; 替换临时标签
    (goto-char (point-max))
    (while (re-search-backward (concat unique "\\([0-9]+\\)") nil t)
      (replace-match (format "%s%s" "fig" (match-string 1)) nil nil nil nil))
    ))
1 个赞

有点明白了,如果我没有理解错的话,跟 org-footnote-normalize 有些相似,就是把第一个 \label{figXXX} 换成 \label{fig1},然后依此类推,同时原来 \cite{figXXX} 的对应关系也要保持一致。这样的话,你可以试试找出所有的 \label{figXXX} 如 fig2、fig3、fig1,然后建立一个替换关系

((fig2 . fig1)
 (fig3 . fig2)
 (fig1 . fig3))

然后把所有的 figXXX 都按照这个关系替换。下面的命令是按这个思路实现的,或许有所帮助。

(defun jerry-latex-normalize-label (beg end)
  (interactive "r")
  (let (matches alist)
    ;; Find labels
    (save-excursion
      (goto-char beg)
      (while (re-search-forward
              (rx "\\label{fig" (group (1+ digit)) "}")
              end t)
        (push (string-to-number (match-string 1)) matches))
      (setq matches (nreverse matches)))
    ;; Build alist for replacement
    (setq alist
          (loop for new from 1
                for old in matches
                collect (cons old new)))
    ;; Replace
    (save-excursion
      (goto-char beg)
      (while (re-search-forward
              (rx "\\" (or "label" "cite") "{fig" (group (1+ digit)) "}")
              end t)
        (replace-match
         (number-to-string
          (cdr (assq (string-to-number (match-string 1))
                     alist)))
         nil t nil 1)))))

第一个例子

\label{fig4} \label{fig3} \label{fig1} \cite{fig4}

=>

\label{fig1} \label{fig2} \label{fig3} \cite{fig1}

第二个例子

\label{fig2}
\label{fig1}
 \cite{fig1}
 \cite{fig2}

=>

\label{fig1}
\label{fig2}
 \cite{fig2}
 \cite{fig1}

恩,就是这个意思,这个建立对应关系的思路不错