2015-02-24 52 views
1

在啓用了iimage-mode的emacs組織模式下,它可以顯示來自相對文件路徑的內嵌圖像,如: [[file:images/foo .JPG]emacs可以以組織模式在zip壓縮文件中顯示圖像

我要的是:怎麼能顯示一個zip壓縮包的圖像定位,就像這樣: [[文件:images.zip/foo.jpg] 有沒有一種辦法做這個?

+0

有一個相關的問題emacs stackexchange應該可以幫到你。問題是[如何以組織模式顯示pdf圖像](http://emacs.stackexchange.com/a/401/115)。該解決方案可以修改爲您處理.zip而不是.pdf的使用案例,它會通過'shell-command'而不是'convert'調用'unzip'二進制文件。 – 2015-02-26 20:49:46

+0

是的,通過遵循這個答案,我的目標幾乎達到了。 – lsen 2015-02-27 05:02:01

回答

0

規則這個工作:

  • 如果您有包含圖像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))))))))) 
+0

它工作正常。請注意,不同之處在於,您將圖像文件提取到歸檔文件的相同路徑,並且我將它放在臨時目錄中。 – lsen 2015-02-28 03:59:22

+0

最大的區別是它支持'[[./somedir/zipfile_zip/dir-in-zip/img.png]]'這樣的文件位置,其中zip文件的位置是'。/ somedir/zipfile.zip'。這裏的zip文件名不需要像'arc.zip'這樣的常量。在相同的位置提取的好處是,圖像文件包括將作爲普通圖像包含,如果壓縮文件比已經提取的圖像更舊,則不會重新提取壓縮文件。 – 2015-02-28 05:28:30

+0

當我有機會時,我正在更多地在我的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

0

謝謝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)) 
     ) 
     )))))) 
+0

原來拉鍊需要一個更強大的解決方案;我已經添加了我的答案。作爲你的第一個elisp實驗,你跳進這個很棒。保持下去! :) – 2015-02-27 18:49:49

相關問題