37

由于我使用 Emacs Org 模式作为研究日志,有时我想通过屏幕截图来跟踪某些内容,但我绝对不想保存它们。所以我想知道有没有办法将这些数字插入到我的组织模式文件中,比如从剪贴板中处理它们的单词?

4

8 回答 8

25

您想要的确切功能目前尚未实现,但如果您认为“绝对不想保存它们”,我会怀疑将大量图像保存到研究日志中。

无论如何,近年来,您希望的功能已在 org-mode 邮件列表中多次表达 - 检查

http://comments.gmane.org/gmane.emacs.orgmode/33770

http://www.mail-archive.com/emacs-orgmode@gnu.org/msg50862.html

第一个链接包含一些用于启动屏幕截图实用程序(通过 ImageMagick)的代码,以 [唯一] 保存文件并在 org-mode 缓冲区中插入内联链接。

如该线程中所述,该代码已得到改进并添加到 org-mode hacks 页面 - 该页面有很多有用的宝石:

http://orgmode.org/worg/org-hacks.html

(defun my-org-screenshot ()
  "Take a screenshot into a time stamped unique-named file in the
same directory as the org-buffer and insert a link to this file."
  (interactive)
  (setq filename
        (concat
         (make-temp-name
          (concat (buffer-file-name)
                  "_"
                  (format-time-string "%Y%m%d_%H%M%S_")) ) ".png"))
  (call-process "import" nil nil nil filename)
  (insert (concat "[[" filename "]]"))
  (org-display-inline-images))
于 2013-07-03T01:08:05.470 回答
19

对于 OS X 用户。以下恭维 Assem 的回答

这个命令对我不起作用,所以我用一个参数import把它换成了。我还发现使用相对路径而不是绝对路径更方便。screencapture-i

(defun my-org-screenshot ()
  "Take a screenshot into a time stamped unique-named file in the
same directory as the org-buffer and insert a link to this file."
  (interactive)
  (setq filename
        (concat
         (make-temp-name
          (concat (file-name-nondirectory (buffer-file-name))
                  "_"
                  (format-time-string "%Y%m%d_%H%M%S_")) ) ".png"))
  (call-process "screencapture" nil nil nil "-i" filename)
  (insert (concat "[[./" filename "]]"))
  (org-display-inline-images))

更新:改进

我最近对脚本进行了一些改进。它现在将屏幕截图放在子目录中,如果需要创建目录,并且仅在实际创建图像时将链接插入 emacs(即,如果您按 ESC,则不执行任何操作)。它也适用于 Ubuntu 和 OS X。

(defun my-org-screenshot ()
  "Take a screenshot into a time stamped unique-named file in the
same directory as the org-buffer and insert a link to this file."
  (interactive)
  (org-display-inline-images)
  (setq filename
        (concat
         (make-temp-name
          (concat (file-name-nondirectory (buffer-file-name))
                  "_imgs/"
                  (format-time-string "%Y%m%d_%H%M%S_")) ) ".png"))
  (unless (file-exists-p (file-name-directory filename))
    (make-directory (file-name-directory filename)))
  ; take screenshot
  (if (eq system-type 'darwin)
      (call-process "screencapture" nil nil nil "-i" filename))
  (if (eq system-type 'gnu/linux)
      (call-process "import" nil nil nil filename))
  ; insert into file if correctly taken
  (if (file-exists-p filename)
    (insert (concat "[[file:" filename "]]"))))
于 2015-08-07T01:54:09.670 回答
9

这里的答案集中在启动 emacs 中的过程。在macos上,另一种方法是使用cmd-ctl-shift-4将屏幕截图图像放在系统剪贴板上,然后返回Emacs并使用emacs lisp调用pngpaste将图像从剪贴板写入文件,然后做任何事情您需要使用图像文件(插入到 org、LaTeX 或作为本机 Emacs 内联图像等)。

例如,要插入 org:

(defun org-insert-clipboard-image (&optional file)
  (interactive "F")
  (shell-command (concat "pngpaste " file))
  (insert (concat "[[" file "]]"))
  (org-display-inline-images))
于 2017-09-17T20:58:21.263 回答
7

(如果使用),我使用@assem 的代码(谢谢v.much btw)并创建了一个版本,而不是创建一个子文件夹(如果它不存在),例如: ${filename}IMG/ 然后放一个图像像 img_date.png 进入该文件夹,然后将相对路径插入缓冲区,如:
[[ ./${filename}IMG/img_2015...png ]]

这是代码:

(defun my-org-screenshot ()
"Take a screenshot into a time stamped unique-named file in the
sub-directory (%filenameIMG) as the org-buffer and insert a link to this file."
(interactive)

(setq foldername (concat (buffer-file-name) "IMG/"))
(if (not (file-exists-p foldername))
  (mkdir foldername))

(setq imgName (concat "img_" (format-time-string "%Y_%m_%d__%H_%M_%S") ".png"))
(setq imgPath (concat (buffer-file-name) "IMG/" imgName))

(call-process "import" nil nil nil imgPath)

(setq relativeFilename (concat "./"
    (buffer-name) "IMG/" imgName))

(insert (concat "[[" relativeFilename "]]"))
(org-display-inline-images)
)

[编辑 2015.04.09]

同时,我发现上述方法效果不佳。从技术上讲,它可以工作,但它会生成许多与文件名匹配的文件夹名称,因为存在具有相似名称的文件夹,因此选择文件很繁琐。

相反,我选择了一个解决方案,将所有 org 文件保存在同一个文件夹中,并有一个包含所有图像的“img”子文件夹。

我使用这样的代码来捕获图像:

(defun my/img-maker ()
 "Make folder if not exist, define image name based on time/date" 
  (setq myvar/img-folder-path (concat default-directory "img/"))

  ; Make img folder if it doesn't exist.
  (if (not (file-exists-p myvar/img-folder-path)) ;[ ] refactor thir and screenshot code.
       (mkdir myvar/img-folder-path))

  (setq myvar/img-name (concat "img_" (format-time-string "%Y_%m_%d__%H_%M_%S") ".png"))
  (setq myvar/img-Abs-Path (concat myvar/img-folder-path myvar/img-name)) ;Relative to workspace.

  (setq myvar/relative-filename (concat "./img/" myvar/img-name))
  (insert "[[" myvar/relative-filename "]]" "\n")
)

(defun my/org-screenshot ()
  "Take a screenshot into a time stamped unique-named file in the
 sub-directory (%filenameIMG) as the org-buffer and insert a link to this file."
  (interactive)
  (my/img-maker)
  ;(make-frame-invisible)
  (lower-frame)
  (call-process "import" nil nil nil myvar/img-Abs-Path)

  (raise-frame)
  ;(make-frame-visible)
  (org-display-inline-images)
)

和我的 org/img 文件夹中的一个小 bash 脚本来存档未引用的图像:

#!/bin/sh 

cd ~/git/LeoUfimtsev.github.io/org/img/
mkdir ~/git/LeoUfimtsev.github.io/org/img/archive
FILES=~/git/LeoUfimtsev.github.io/org/img/*.png
for f in $FILES
do
  var_grep_out=$(grep --directories=skip $(basename $f) ../*)
  if [ -z "$var_grep_out" ];
  then 
     echo "Archiving: $f"
     mv $f archive/
  fi
done
于 2015-01-27T21:30:53.440 回答
5

我喜欢与 org 文件一起属于的图像和其他材料位于明确关联的目录中。我为此使用了 org-attachment 机制,并在几年前写了一个包org-attachment-screenshot,它也可以从 MELPA 获得。它允许为附件提供定义目录名称(例如文档名称+某些后缀)的功能,并且还将支持标准附件功能,例如,如果您想基于条目定义附件,并在条目内继承。还为要执行的快照命令提供可自定义的变量。请看一看。

于 2016-09-28T14:05:36.510 回答
4

我的解决方案是针对 Windows 平台的。非常感谢Assem提供了我所基于的解决方案。

我编写了一个 C# 控制台应用程序CbImage2File,它将剪贴板上的图像(如果有的话)写入作为命令行参数给出的路径。您将需要对System.Windows.Forms程序集的引用。

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);
        }
    }
}

我使用 Greenshot 截取屏幕截图,它(通过其配置)自动将屏幕截图复制到剪贴板。

然后,我使用快捷C-S-v方式使用以下函数将图像粘贴到 org 模式缓冲区中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)

这个函数会计算出一个文件路径,然后调用 C# 应用程序来创建png文件,然后它会添加图像标签,然后调用org-display-inline-images来显示图像。如果剪贴板上没有图像,它将粘贴到 C# 应用程序的响应中。

于 2016-08-05T11:34:05.883 回答
4

org-download包就是为此而设计的。

于 2016-09-15T15:48:35.733 回答
4

对于 Windows 10 用户,我修改了@assem 提供的答案以使用开箱即用的工具:

(defun my-org-screenshot ()
  "Take a screenshot into a time stamped unique-named file in the
   same directory as the org-buffer and insert a link to this file."  
   (interactive)
   (setq filename
     (concat
       (make-temp-name
         (concat (buffer-file-name)
              "_"
              (format-time-string "%Y%m%d_%H%M%S_")) ) ".png"))
   (shell-command "snippingtool /clip")
   (shell-command (concat "powershell -command \"Add-Type -AssemblyName System.Windows.Forms;if ($([System.Windows.Forms.Clipboard]::ContainsImage())) {$image = [System.Windows.Forms.Clipboard]::GetImage();[System.Drawing.Bitmap]$image.Save('" filename "',[System.Drawing.Imaging.ImageFormat]::Png); Write-Output 'clipboard content saved as file'} else {Write-Output 'clipboard does not contain image data'}\""))
   (insert (concat "[[file:" filename "]]"))
   (org-display-inline-images))

完整的文章可以在这里找到

于 2018-11-25T20:10:20.693 回答