#contents * image-diredで,ディレクトリやアーカイブファイルの表紙を表示する [#c32a19a7] 表題のようなことができたら便利だと思いましたので,image-diredの2つの関数を 編集してみます。 TODO: - 非同期実行(deferred) - 正規表現見直し(とくにcase) - tar.gz, rar対応 - ディレクトリから表紙画像を選ぶためのより賢い方法 - rubyスクリプトの,ハードコードな箇所の修正 - xcf, psd, pdf対応 ** 準備 [#a6c01fe6] (require 'image-dired) (call-process "mkdir" nil nil nil "-p" "/dev/shm/image-dired/temp") (custom-set-variables '(image-dired-dir "/dev/shm/image-dired")) (setq image-dired-archive-file-pattern "\\.\\(zip\\|ZIP\\)$") (define-key dired-mode-map (kbd "C-x t") 'image-dired-dired-toggle-marked-thumbs) ** image-dired-dired-toggle-marked-thumbs [#w4ccbf4b] (defun image-dired-dired-toggle-marked-thumbs (&optional arg) ;; argがnon-nil の場合は,マークされたファイルのかわりに ;; 指定されたファイルを対象にします. (interactive "P") (dired-map-over-marks ;; それぞれのマークされた行について ;; body(第一引数)を評価して,結果のリストを返します. (let* ((image-pos (dired-move-to-filename)) ;; 画像を挿入する位置 (image-file (dired-get-filename nil t)) ;; 画像ファイル名 thumb-file ;; サムネイルファイル(?) overlay) ;; オーバーレイ(?) (when (and image-file (or (file-directory-p image-file) (string-match-p image-dired-archive-file-pattern image-file) (string-match-p (image-file-name-regexp) image-file))) ;; 画像ファイル名が non-nilで,かつ ;; ファイル名が image-file-name-regexp(\\.BMPとか) ;; に一致するとき ;; 式1 (setq thumb-file (image-dired-get-thumbnail-image image-file)) ;; 式2 ;; If image is not already added, then add it. (let* ((cur-ovs (overlays-in (point) (1+ (point)))) (thumb-ov (car (cl-remove-if-not (lambda (ov) (overlay-get ov 'thumb-file)) cur-ovs)))) (if thumb-ov (delete-overlay thumb-ov) (put-image thumb-file image-pos) (setq overlay (cl-loop for o in (overlays-in (point) (1+ (point))) when (overlay-get o 'put-image) collect o into ov finally return (car ov))) (overlay-put overlay 'image-file image-file) (overlay-put overlay 'thumb-file thumb-file))))) (if thumb-file (let* ((cur-ovs (overlays-in (point) (1+ (point)))) (thumb-ov (car (cl-remove-if-not (lambda (ov) (overlay-get ov 'thumb-file)) cur-ovs)))) (if thumb-ov (delete-overlay thumb-ov) (put-image thumb-file image-pos) (setq overlay (cl-loop for o in (overlays-in (point) (1+ (point))) when (overlay-get o 'put-image) collect o into ov finally return (car ov))) (overlay-put overlay 'image-file image-file) (overlay-put overlay 'thumb-file thumb-file)))))) arg ; Show or hide image on ARG next files. 'show-progress) ; Update dired display after each image is updated. (add-hook 'dired-after-readin-hook 'image-dired-dired-after-readin-hook nil t)) ** image-dired-get-thumbnail-image [#t300d3e6] (defun image-dired-get-thumbnail-image (file) "Return the image descriptor for a thumbnail of image file FILE." ;; サムネイル画像のディスクリプタ(FILE)をかえす. (message "image-dired-get-thumbnail-image") (unless (or (string-match (image-file-name-regexp) file) (string-match image-dired-archive-file-pattern file) (file-directory-p file)) (error "%s is not a valid image file" file)) ;; 引数が image-file-name-regexp にマッチしないときは ;; エラーをかえす. (let ((thumb-file (image-dired-thumb-name file))) ;; file に, ディレクトリのハッシュ値をつけた絶対パス(文字列) (unless (and (file-exists-p thumb-file) ;; サムネイルファイルがナイこと,かつ (<= (float-time (nth 5 (file-attributes file))) (float-time (nth 5 (file-attributes thumb-file))))) ;; サムネイルファイルが,元のファイルより古い場合 ;; アーカイブファイルの場合: ;; 1. file(zipファイル名)から,表紙画像をとりだして ;; (image-dired-dir)に展開する ;; 2. file を,1.でつくったファイル名で上書きする (if (string-match image-dired-archive-file-pattern file) (progn (setq file (shell-command-to-string (concat "archiveImageThumb.rb " file))) (message "archivefile's thumb: %s" file))) ;; file がディレクトリのときは,ディレクトリ内の表紙ファイルに ;; 置換する->対象ディレクトリ内のファイルを数字順にソート ;; TODO: 画像以外のファイルがある場合(Thumbs.dbとか),コケる. (if (file-directory-p file) (progn (setq file (concat file "/" (cond ( (string-match image-dired-archive-file-pattern file) (progn (message "shell-command: %s" (concat "archiveImageThumb.rb " (shell-quote-argument file) )) (setq file (shell-command-to-string (concat "archiveImageThumb.rb " (shell-quote-argument file) ))) (message "archivefile's thumb: %s" file)) ) ( (file-directory-p file) (progn (setq file (concat file "/" (shell-command-to-string (concat "find " file " -type f | " (concat "find " file " -maxdepth 1 -type f |" "sed 's!^.*/!!' | " "grep -E -i '\\.(png|gif|jpeg|jpg)$' | " "sort -n | " "head -1 | " "tr -d '\\n' " )))) (message file))) (message "file: %s" file)) ) ) (image-dired-create-thumb file thumb-file)) ;; サムネイルを生成しておく (message "creating image thumb...") (create-image thumb-file) (if (string-match (image-file-name-regexp) file) (let ((thumb-file (image-dired-thumb-name file))) ;; file に, ディレクトリのハッシュ値をつけた絶対パス(文字列) (unless (and (file-exists-p thumb-file) ;; サムネイルファイルがナイこと,かつ ;; (list 'image :type 'jpeg ;; :file thumb-file ;; :relief image-dired-thumb-relief :margin image-dired-thumb-margin) )) (<= (float-time (nth 5 (file-attributes file))) (float-time (nth 5 (file-attributes thumb-file))))) ;; サムネイルファイルが,元のファイルより古い場合 (image-dired-create-thumb file thumb-file)) ;; サムネイルを生成しておく (message "creating image thumb...: %s, %s" file thumb-file) (create-image thumb-file) ;; (list 'image :type 'jpeg ;; :file thumb-file ;; :relief image-dired-thumb-relief :margin image-dired-thumb-margin) ) nil)) ** image-dired-dired-remove-marked-thumbs [#qafa1561] 暫定。ムダに重い。 (defun image-dired-dired-remove-marked-thumbs (&optional arg) (interactive "P") (dired-map-over-marks (let* ((image-pos (dired-move-to-filename)) (image-file (dired-get-filename nil t)) thumb-file overlay) (when (and image-file (or (file-directory-p image-file) (string-match-p image-dired-archive-file-pattern image-file) (string-match-p (image-file-name-regexp) image-file))) (setq thumb-file (image-dired-get-thumbnail-image image-file)) (if thumb-file (let* ((cur-ovs (overlays-in (point) (1+ (point)))) (thumb-ov (car (cl-remove-if-not (lambda (ov) (overlay-get ov 'thumb-file)) cur-ovs)))) (if thumb-ov (delete-overlay thumb-ov) ))))) arg ; Show or hide image on ARG next files. 'show-progress) ; Update dired display after each image is updated. (add-hook 'dired-after-readin-hook 'image-dired-dired-after-readin-hook nil t)) ** archiveImageThumb.rb [#g0ee14ae] 以下は,zipファイルから1枚の画像ファイルを選んで, "/dev/shm/image-dired/temp"に展開するスクリプトです. パスのとおった場所に保存しておきます. #!/usr/bin/ruby require("digest/md5"); fileList= []; if(ARGV[0] =~ /^.*\.(zip|ZIP)$/) filename= File.basename(ARGV[0]); buf= `unzip -l '#{ARGV[0]}' `.lines[3..-3] buf.each{|l| l= l.strip(); if( l =~ /\.(jpg|JPG|jpeg|JPEG|png|PNG)$/) # extract file name col l =~ /\d+ +\d\d-\d\d-\d{4} +\d\d:\d\d +(.*)$/; fileList.push( $~[1] ); end } fileList= fileList.sort(); digest = Digest::MD5.hexdigest(ARGV[0]); extname= File.basename( "/dev/shm/image-dired/temp/" + fileList[0] ); `unzip -o '#{ARGV[0]}' #{fileList[0]} -d /dev/shm/image-dired/temp` `mv '/dev/shm/image-dired/temp/#{fileList[0]}' '/dev/shm/image-dired/temp/#{digest}_#{extname}' ` printf( "/dev/shm/image-dired/temp/#{digest}_#{extname}" ); else `touch /dev/shm/image-dired/archiveImageThumb.rb-error` end