在啓用了iimage-mode的emacs組織模式下,它可以顯示來自相對文件路徑的內嵌圖像,如: [[file:images/foo .JPG]emacs可以以組織模式在zip壓縮文件中顯示圖像
我要的是:怎麼能顯示一個zip壓縮包的圖像定位,就像這樣: [[文件:images.zip/foo.jpg] 有沒有一種辦法做這個?
在啓用了iimage-mode的emacs組織模式下,它可以顯示來自相對文件路徑的內嵌圖像,如: [[file:images/foo .JPG]emacs可以以組織模式在zip壓縮文件中顯示圖像
我要的是:怎麼能顯示一個zip壓縮包的圖像定位,就像這樣: [[文件:images.zip/foo.jpg] 有沒有一種辦法做這個?
規則這個工作:
myimage.png
一個zip文件zippedimg.zip
,你應該在組織模式文件中引用它作爲[[./zippedimg_zip/myimage.png]]
。請注意,我已將zippedimg.zip
中的.
替換爲_
。[[
和]]
中提到的相同的目錄。但是,由於zippedimg.zip
文件存在,emacs不允許創建具有相同名稱的目錄。因此,對於zippedimg.zip
文件,我只提取其中的圖像,同時保留zip中的路徑爲zippedimg_zip
目錄。這裏是工作的組織文件來測試它出的最小值:
#+TITLE: Image from archive
#+STARTUP: inlineimages
#+NAME: fig:myimage
#+HEADER: :extractfromarchive t
# The below caption line is optional
#+CAPTION: My image myimage.png inside ./zippedimg.zip
[[./zippedimg_zip/myimage.png]]
以下是你需要把你的Emacs的某處代碼初始化:
;; Execute the `modi/org-include-img-from-archive' function just before saving the file
(add-hook 'before-save-hook #'modi/org-include-img-from-archive)
;; Execute the `modi/org-include-img-from-archive' function before processing the
;; file for export
(add-hook 'org-export-before-processing-hook #'modi/org-include-img-from-archive)
(defun modi/org-include-img-from-archive (&rest ignore)
"Extract image files from the archive files. Only .zip files are supported
as of now.
Only looks at #HEADER: lines that have \":extractfromarchive t\".
This function does nothing if not in org-mode, so you can safely
add it to `before-save-hook'."
(interactive)
(when (derived-mode-p 'org-mode)
(save-excursion
(goto-char (point-min)) ; go to the beginning of the buffer
(while (search-forward-regexp
"^\\s-*#\\+HEADER:.*\\s-:extractfromarchive\\s-+t"
nil :noerror)
(let (;; only .zip supported as of now
(search-expr "\\[\\[\\(.*?\\)_zip/\\(.*?\\)\\([^/]+\\..*\\)\\]\\]")
arc-file
path-in-arc-file
img-file img-file-full-path
dest-dir dest-dir-full-path
cmd)
;; Keep on going on to the next line till it finds a line with
;; `[[./path/to/zip-file/path/inside/zip/to/the/image]]'
(while (progn
(forward-line 1)
(or (not (looking-at search-expr))
(eobp))))
(when (looking-at search-expr)
(setq arc-file (expand-file-name
(concat (match-string-no-properties 1) ".zip")))
(setq path-in-arc-file (match-string-no-properties 2))
(setq img-file (match-string-no-properties 3))
(setq dest-dir (concat "./" (file-name-base arc-file)
"_zip/" path-in-arc-file))
(setq dest-dir-full-path (concat (file-name-sans-extension arc-file)
"_zip/" path-in-arc-file))
(setq img-file-full-path (expand-file-name img-file dest-dir))
;; (message (concat "arc-file: %s\npath-in-arc-file: %s\n"
;; "img-file: %s\nimg-file-full-path: %s\n"
;; "dest-dir: %s\ndest-dir-full-path: %s")
;; arc-file path-in-arc-file
;; img-file img-file-full-path
;; dest-dir dest-dir-full-path)
(when (file-newer-than-file-p arc-file img-file-full-path)
;; This block is executed only if arc-file is newer than
;; img-file-full-path
;; or if img-file does not exist
;; https://www.gnu.org/software/emacs/manual/html_node/elisp/Testing-Accessibility.html
(when (file-exists-p dest-dir-full-path)
(delete-directory dest-dir-full-path t t))
(make-directory dest-dir-full-path t)
(setq cmd (format "unzip -j %s %s%s -d ./%s."
arc-file path-in-arc-file img-file
(concat (file-name-base arc-file) "_zip/"
path-in-arc-file)))
(message "%s" cmd)
(shell-command cmd)
(shell-command (concat "touch " img-file-full-path)))))))))
它工作正常。請注意,不同之處在於,您將圖像文件提取到歸檔文件的相同路徑,並且我將它放在臨時目錄中。 – lsen 2015-02-28 03:59:22
最大的區別是它支持'[[./somedir/zipfile_zip/dir-in-zip/img.png]]'這樣的文件位置,其中zip文件的位置是'。/ somedir/zipfile.zip'。這裏的zip文件名不需要像'arc.zip'這樣的常量。在相同的位置提取的好處是,圖像文件包括將作爲普通圖像包含,如果壓縮文件比已經提取的圖像更舊,則不會重新提取壓縮文件。 – 2015-02-28 05:28:30
當我有機會時,我正在更多地在我的git中優化這個函數:https://github.com/kaushalmodi/.emacs.d/blob/master/elisp/org-include-img-from-archive /org-include-img-from-archive.el最終目標是支持不同的存檔格式。 – 2015-02-28 05:30:22
謝謝kaushalmodi, 下面是我所做的,按照這個問題的答案how to display pdf images in org mode。由於這是我第一次執行lisp編程,所以代碼可能設計得不好。
(add-hook 'org-mode-hook #'modi/org-include-img-from-zip)
(defun modi/org-include-img-from-zip (&rest ignore)
"extract images from zip an archive.
This function does nothing if not in org-mode."
(interactive)
(when (derived-mode-p 'org-mode)
(save-excursion
(goto-char (point-min))
(while (search-forward-regexp
"^\\s-*#\\+STARTUP:.*\\s-convertfromzip"
nil 'noerror)
(let* (filenoext imgext imgfile imgfilename zipfile imgpath cmd)
(setq zipfile "arc.zip")
;; Keep on going on to the next line till it finds a line with
;; `[[FILE]]'
(while (progn
(forward-line 1)
(not (looking-at "\\[\\[\\(.*\\)\\.\\(.*\\)\\]\\]"))))
(when (looking-at "\\[\\[file:\\(.*\\)\\.\\(.*\\)\\]\\]")
(setq filenoext (match-string-no-properties 1))
(setq imgext (match-string-no-properties 2))
(setq imgpath (concat filenoext "." imgext))
(setq imgfile (expand-file-name (concat filenoext "." imgext)))
(setq imgfilename (file-name-nondirectory imgfile))
(when (string= (substring imgpath 0 1) "~")
(setq imgpath (concat "%HOME%" (substring imgpath 1 nil)))
(setq imgpath (file-name-directory imgpath))
(setq cmd (concat "7z e " zipfile " -y -o"imgpath " " imgfilename " " imgfilename))
(with-temp-buffer (shell-command cmd t))
)
))))))
原來拉鍊需要一個更強大的解決方案;我已經添加了我的答案。作爲你的第一個elisp實驗,你跳進這個很棒。保持下去! :) – 2015-02-27 18:49:49
有一個相關的問題emacs stackexchange應該可以幫到你。問題是[如何以組織模式顯示pdf圖像](http://emacs.stackexchange.com/a/401/115)。該解決方案可以修改爲您處理.zip而不是.pdf的使用案例,它會通過'shell-command'而不是'convert'調用'unzip'二進制文件。 – 2015-02-26 20:49:46
是的,通過遵循這個答案,我的目標幾乎達到了。 – lsen 2015-02-27 05:02:01