【问题标题】:How to replace all occurrences in emacs?如何替换emacs中的所有出现?
【发布时间】:2020-07-17 19:21:48
【问题描述】:

我正在使用 org-mode publish 构建一个博客。但我想编辑 org-mode 给出的默认样式,该版本意味着将一些标签包装在其他标签中(如 divs 标签)。所以我构建它的方式是基于一些想法(查看下面的链接)。

例如下面的函数将一个类属性添加到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 了解不多......所以如果有人知道如何继续(或有解决方案)解决这个问题,我会很高兴:)

【问题讨论】:

    标签: html emacs org-mode


    【解决方案1】:

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

    我创建了这个函数(注意:你可以看到这个函数没有优化但是可以工作,也许我会编辑这个答案来发布最终优化的解决方案):

    (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
          )
      )
    

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

    (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:如果这个答案对您有帮助,请投票。我花了大约三天的时间研究和测试以达到这个解决方案。谢谢!

    【讨论】:

      【解决方案2】:

      我认为你不应该保存文本。只需插入您想要的东西。

          (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 (describe-function)。

      【讨论】:

      • 问题是每个href很可能指的是不同的图像文件,所以你必须匹配路径名,然后在插入替换文本时将其拼接。
      • 没错。正如@NickD 所说。其实我想出了如何解决这个问题。我稍后会评论我的解决方案。
      猜你喜欢
      • 1970-01-01
      • 2021-12-20
      • 2022-01-19
      相关资源
      最近更新 更多