; -*- emacs-lisp -*- ; ; bins-mode: simple replacement for bins-edit-gui ; Mark Eichin 2003 ; ; basically: find-file replacement (and save-hook) ; load the image, and load any existing XML properties into rfc822 headers ; on save, just put the headers back into the XML ; call out to a helper program if needed (also to later get exif rotation) ; make fields work like... custom? tab/backtab at least ; add auto-fill-from-recent ; add fix-rotation ; ; consider just saving them as rfc822 and converting later ; consider (defun system (program &rest args) (let ( (b (get-buffer-create "*IMG*")) ) (apply 'call-process program nil b nil args) (set-buffer b) (let ( (s (buffer-string) ) ) (kill-buffer b) s))) (defun bins-save-hook () (goto-char (point-max)) (delete-char -1) (bins-scan-recent-headers) ) (defvar bins-mode-map nil "Local map for bins.") (or bins-mode-map (let ((map (make-sparse-keymap))) (define-key map "\M-r" 'bins-revert) (define-key map "\M-n" 'bins-next-img) (define-key map "\M-p" 'bins-prev-img) (define-key map "\M-a" 'bins-fill-in) (define-key map "\M-s" 'save-buffer) (setq bins-mode-map map))) ; for i in *.jpg; do time /sw/bin/convert -geometry 579x439 $i $i.toenail; done (defun bins-load-img (filename) (interactive "fImage: ") (let* ( ;* for cache-img (buffer (generate-new-buffer (format "bins:%s" (file-name-nondirectory filename)))) (cache-img (format "%s.toenail" filename)) (img (create-image (if (file-exists-p cache-img) (system "cat" (expand-file-name cache-img)) (system "/sw/bin/convert" "-geometry" (format "%dx%d" (* 0.6 (frame-pixel-width)) (* 0.6 (frame-pixel-height))) ; "300x1000" - actually, "579x439" on kirameki-neko (expand-file-name filename) "-")) nil t)) (captname (concat filename ".capt")) ) ; we may need to use file->string because of the changing bug... ; (setq img (create-image bins-img-tmp)) ; (setq img (debian-file->string bins-img-tmp) nil t)) (switch-to-buffer buffer) (use-local-map bins-mode-map) (insert-image img "\n") (goto-char 0) (setq buffer-file-name captname) (if (file-exists-p captname) (progn (insert-file-contents-literally captname) (bins-scan-recent-headers) ) (insert "Title: \n" "Description: \n" "Event: \n" "People: \n" "Location: \n" )) (set-buffer-modified-p nil) ;just an empty template doesn't count either (add-hook 'write-contents-hooks 'bins-save-hook) )) (defun bins-basename (filename ext) (string-match (format "^\\(.*\\)\\.%s$" ext) filename) (match-string 1 filename)) ; (bins-basename "/asljdf/dljf/foo.bar.capt" "capt") (defun bins-revert () (interactive) (let ((imgname (bins-basename buffer-file-name "capt"))) (if (kill-buffer nil) (bins-load-img imgname)))) ; in python: ; stash = {} ; def bins_scan_recent_headers(buf): ; stash.update(dict([re.match("^(\S+): (.)*$", line).groups() for line in buf.splitlines()])) (setq stash (make-hash-table :test 'equal)) ; (append (list 'a 'b) (list 'c)) ; ; (setq bins-result "") ; (defun bins-prin1-accum (x y) (setq bins-result (concat bins-result x ": " y "\n"))) ; (maphash 'bins-prin1-accum stash) ; (puthash "A" "B" stash) (defun bins-scan-recent-headers () (save-excursion (goto-char (point-min)) (while (< (point) (- (point-max) 1)) (apply 'puthash (append (bins-scan-one-header) (list stash)))))) (defun bins-scan-one-header () (let ( (eolpoint (save-excursion (end-of-line) (+ 1 (point)))) ) (search-forward-regexp "\\([^:]+\\): \\(.*\\)$" eolpoint 'noerror) (forward-char 1) (list (match-string 1) (match-string 2)) )) (defun bins-fill-in () (interactive) (save-excursion (goto-char (point-min)) (while (< (point) (- (point-max) 1)) (let* ( (h (bins-scan-one-header)) (tag (nth 0 h)) (val (nth 1 h)) ) (if (string= val "") (progn (backward-char 1) (insert (gethash tag stash "")) (forward-char 1))))))) (defun bins-next-img () (interactive) ; figure out the saved image (let* ( (file (bins-basename (expand-file-name buffer-file-name) "capt")) (dir (file-name-directory file)) (files (directory-files dir t ".*\.[Jj][Pp][Gg]$")) ) (while (and files (not (equal file (car files)))) (setq files (cdr files))) (if (kill-buffer nil) (progn (message "%s" (car (cdr files))) (bins-load-img (car (cdr files))))) ) ) (defun bins-prev-img () (interactive) ; figure out the saved image (let* ( (file (bins-basename (expand-file-name buffer-file-name) "capt")) (dir (file-name-directory file)) (files (directory-files dir t ".*\.[Jj][Pp][Gg]$")) ) (while (and files (not (equal file (car (cdr files))))) (setq files (cdr files))) (if (kill-buffer nil) (progn (message "%s" (car files)) (bins-load-img (car files)))) ) ) ;; ;; check file datestamps, do some trivial 1/N support? ;; ;; (nth 5 (file-attributes FILENAME)) = last mod