如何替换 emacs 中的所有事件?

How to replace all occurrences in emacs?

我正在使用组织模式发布构建博客。但我想编辑 org-mode 给出的默认样式,该版本意味着将一些标签包装在其他标签中(如 div 标签)。所以我构建它的方式是基于一些想法(检查下面的 link)。

例如下面的函数将 class 属性添加到 body 标签中,并且有效! (思路基于this question

(defun my-html-body-onload-filter (output backend info)
"Add class to<body>  tag, if any."
(when (and (eq backend 'html)
       (string-match "<body>\n" output))
  (replace-match "<body class='uk-container-small uk-align-center uk-text-justify'> \n" nil nil output))
  )

所以我现在想做的是将 img 标签包装在其他标签中。我不是 elisp 程序员,但我正在尝试构建一个函数来达到某种解决方案。 所以实际的问题是这样的: 我有这个:

<img src="images/photo.jpg" alt="">

我需要包装 img 标签,这样我才能看到下一个输出:

<div uk-lightbox="animation: slide">
    <a href="images/photo.jpg">
        <img src="images/photo.jpg" alt="">
    </a>
</div>

到目前为止,我创建了这个小函数来提取 src 值:

(defun xe ()
  (interactive)
  (search-forward "<img src=\"")
  (defvar x-start (point))
  (search-forward "\"")
  (backward-char)
  (defvar x-end (point))
  (kill-ring-save x-start x-end)
)

但我感觉很迷茫,因为我对 elisp 了解不多......所以如果有人知道如何继续(或有解决方案)来解决这个问题,我会很高兴:)

我认为你不应该保存文本。只需插入您想要的内容即可。

    (while (search-forward "<img src=\"" nil t nil)
      
        (goto-char (match-beginning 0)) 
        (insert "<div uk-lightbox=\"animation: slide\"><a href=\"images/photo.jpg\">")
        (search-forward ">")
        (insert "</a></div>"))

如果您想了解有关函数的更多信息,请使用 C-h f(描述函数)。

你好,这是我的最终解决方案:

我创建了这个函数(注意:如你所见,这个函数没有优化但有效,也许我会把这个答案编辑为post最终优化的解决方案):

(defun wrap-img-tags ()
  (setq text-to-search-1 "<img src=\"")
  (goto-char (point-min))
  (setq ntimes (count-matches text-to-search-1))

  (if (> ntimes 0)
      (cl-loop repeat ntimes do ;; this is like a for loop

       (search-forward "<img src=\"" nil t)
       (setq x-start (point))
       (search-forward "\"")
       (backward-char)
       (setq x-end (point))
       (kill-ring-save x-start x-end)
       (beginning-of-line)
       (insert (format "\n<div uk-lightbox=\"animation: slide\">
     <a href=\"%s\">\n" (car kill-ring)))
       (indent-for-tab-command)
       (forward-line)
       (insert (format "</a>\n</div>"))
                 
       )
      
      nil
      )
  )

此外,我想在某些标签上添加 class 属性 ,所以我 创建了下一个函数

(defun add-class-to-tag (tag class)
  "Add class attribute with the class variable value.
TAG: Tag to modify.
CLASS: Class in string form to add."
;  (interactive "sTag:\nsClass:")

  (setq text-to-search (format "<%s" tag))
  (goto-char (point-min))

  (setq does-it-have-class-attribute t)
  (cl-loop repeat (how-many text-to-search)  do ;; this is like a for loop
       
       (search-forward text-to-search)
       (setq x-start (point))

       (setq does-it-have-class-attribute (search-forward
                           "class=\""
                           (line-end-position)
                           t ; if fails return nil
                           ))

       (if (not does-it-have-class-attribute)

           (progn
         (insert (format " class=\"%s\"" class))
         (setq does-it-have-class-attribute nil)
         )

         (progn ; else
           (search-forward "\"")
           (backward-char)
           (insert (format " %s" class))

           ))
       )
  
  )

最后,我在创建的 html 文件的预最终处理器上执行它: (以下函数思路取自this blog

(defun org-blog-publish-to-html (plist filename pub-dir)
  "Same as `org-html-publish-to-html' but modifies html before finishing."
  (let ((file-path (org-html-publish-to-html plist filename pub-dir)))
    (with-current-buffer (find-file-noselect file-path)
      (wrap-img-tags);; Here I'm executing the first solution
      (add-class-to-tag "h2" "uk-heading-bullet")
      (add-class-to-tag "section" "uk-card uk-card-body uk-align-center uk-text-justify")
      (add-class-to-tag "h1" "uk-h2 uk-panel uk-padding uk-background-secondary uk-light uk-margin-left uk-margin-right")
      (save-buffer)      
      (kill-buffer))
    file-path))

就是这样!它有效:)

此外,我会修改 wrap-img-tags 函数,用其他所需的标签包装任何类型的标签!

PD:如果这个回答对您有帮助,请点赞。我花了大约三天的时间研究和测试以找到这个解决方案。谢谢!