Paste an image on clipboard to Emacs Org mode file without saving it

后端 未结 8 1090
慢半拍i
慢半拍i 2021-01-30 09:21

As I\'m using the Emacs Org mode as a research log, sometime I want to keep track of something via screenshot images, and I definitely don\'t want to save them. So I\'m wonderin

8条回答
  •  我在风中等你
    2021-01-30 09:42

    My solution is for the Windows platform. Many thanks to Assem for giving his solution on which I based mine.

    I wrote a C# console app CbImage2File that writes the image on the clipboard (if there is one) to a path given as the command line argument. You will need a reference to System.Windows.Forms assembly.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace CbImage2File
    {
        class Program
        {
            private static int FAILURE = 1;
    
            private static void Failure(string description)
            {
                Console.Error.WriteLine("Clipboard does not contain image data");
                Environment.Exit(FAILURE);
            }
    
            [STAThread]
            static void Main(string[] args)
            {
                var image = System.Windows.Forms.Clipboard.GetImage();
    
                if (image == null)
                {
                    Failure("Clipboard does not contain image data");
                }
    
                if (args.Length == 0)
                {
                    Failure("You have not specified an output path for the image");
                }
    
                if (args.Length > 1)
                {
                    Failure("You must only specify a file path (1 argument)");
                }
    
                var filePath = args[0];
                var folderInfo = new System.IO.FileInfo(filePath).Directory;
    
                if (!folderInfo.Exists)
                {
                    System.IO.Directory.CreateDirectory(folderInfo.FullName);
                }
    
                image.Save(filePath);
            }
        }
    }
    

    I use Greenshot to take the screenshot, which (via its configuration) automatically copies the screenshot to the clipboard.

    I then use a shortcut C-S-v to paste the image in the org mode buffer using the function org-insert-image-from-clipboard:

    (defun org-insert-image-from-clipboard ()
      (interactive)
      (let* ((the-dir (file-name-directory buffer-file-name))
         (attachments-dir (concat the-dir "attachments"))
         (png-file-name (format-time-string "%a%d%b%Y_%H%M%S.png"))
         (png-path (concat attachments-dir "/" png-file-name))
         (temp-buffer-name "CbImage2File-buffer"))
        (call-process "C:/_code/CbImage2File/CbImage2File/bin/Debug/CbImage2File.exe" nil temp-buffer-name nil png-path)
        (let ((result (with-current-buffer temp-buffer-name (buffer-string))))
          (progn
        (kill-buffer temp-buffer-name)
        (if (string= result "")
            (progn 
              (insert (concat "[[./attachments/" png-file-name "]]"))
              (org-display-inline-images))
          (insert result))))))
    
    (define-key org-mode-map (kbd "C-S-v") 'org-insert-image-from-clipboard)
    

    This function will work out a file path, then invoke the C# app to create png file, then it will add the image tag and then call org-display-inline-images to show the image. If there is no image on the clipboard, it will paste in the response from the C# app.

提交回复
热议问题