org-mode – Dibujar una imagen fuera de emacs y usarla en org

Pregunta:

Decidí usar la combinación asesina emacs + org mode + latex para tomar mis lecciones en la escuela, lo único que me obliga a usar papel y no ser un estudiante ecológico es dibujar y pintar esquemas …

Soy consciente de que hay algunos modos que te permiten dibujar algo en ascii, algunos pueden usar el mouse (como el modo de artista integrado) y exportarlo como una imagen real, pero no me atrae la programación de imágenes también.

Lo que sería la mejor solución para mí es ejecutar rápidamente una aplicación de pintura desde emacs que exportará por defecto la imagen en una ubicación que emacs conocería para que los enlaces a la imagen se inserten automáticamente.

Estoy seguro de que es posible, creo que no requiere tanto conocimiento de lisp, pero aún necesito ayuda …

Sé que puedo ejecutar un comando externo con el ejecutivo, es posible que pueda pasar la ubicación en el argumento del programa de pintura e insertar el enlace no será demasiado difícil.

Necesito tu ayuda para administrar el nombre de las imágenes.

¿Cómo puedo obtener diferentes nombres predeterminados para cada imagen?

¿Sería posible recuperar el nombre para poder guardarlo con otro nombre?

¿Y cómo puedo volver a abrir la aplicación para modificar la imagen? (como Cc Cc es capaz de reevaluar el código fuente …)

Nunca he codificado en lisp, pero después de configurar un poco emacs no parece difícil …

¡Estoy entusiasmado con la codificación lisp! Aunque necesito tu ayuda.

ps: no conozco extensiones que hagan el truco, dime si hay algunas.

Respuesta:

El siguiente código le brinda casi lo que desea en un entorno gnu / linux o cygwin. (No sé si funciona con nt-emacs.) La adaptación a otros entornos debería ser fácil.

  1. ¿Cómo puedo obtener diferentes nombres predeterminados para cada imagen?

    Esa es la única salvedad. Debe ingresar el nombre del archivo usted mismo. Para un ejemplo, ingrese [[file:Images/test.svg]] . La ventaja es que puede elegir un nombre de archivo sano y sabe exactamente dónde reside el archivo. No es necesario que el archivo exista. La opción org-mouse-w32-app-templates proporciona algunos contenidos mínimos para los archivos que deben existir cuando se inicia la aplicación. Solo hay algo para archivos svg todavía. Puede agregar fácilmente otros tipos si lo desea.

  2. ¿Sería posible recuperar el nombre para poder guardarlo con otro nombre?

    Eso no es un problema con 1.

  3. ¿Y cómo puedo volver a abrir la aplicación para modificar la imagen? (como Cc Cc es capaz de reevaluar el código fuente …).

    Eso es lo que realmente hace el código por ti. El tercer botón del mouse en el enlace abre un menú contextual donde puede elegir iniciar la aplicación de Windows para ese enlace. (Puede completar el menú contextual con elementos útiles usted mismo si lo desea). Aquí, en mi casa, inkscape se abre de esta manera. Emacs espera hasta que finalice la aplicación. Si el archivo coincide con una expresión regular para archivos de imagen, las imágenes en el búfer de la organización actual se actualizan a través del proceso-centinela org-mouse-app-update-images .

EDICIÓN 1: Ahora debería ser más independiente del sistema.

(require 'org)

(add-hook 'org-mode-hook '(lambda ()
                (org-defkey org-mouse-map [mouse-3] 'org-mouse-3-menu)))


(defun org-mouse-3-menu (event)
  "Context menu for org-links."
  (interactive "e")
  (let ((selection (x-popup-menu
            event
            (list
             "Org File Menu"
             (list
              ""
              '("Registered Application" . org-mouse-app)
              ;; other nice applications go here
              )))))
    (and selection
     (with-current-buffer (window-buffer (posn-window (event-start event)))
       (call-interactively selection)))))

(defcustom org-mouse-app-templates
  '(("svg" . "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20001102//EN\" \"http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd\"><svg width=\"100%\" height=\"100%\"></svg>"))
  "Some applications bark if they are called with the name of a non-existing file.
This list associates file extensions of non-existing files to some minimal content."
  :type '(alist :key-type string :value-type string)
  :group 'org)

(defvar org-buf)

(defun org-mouse-app-update-images (proc action)
  "Process sentinel for `org-mouse-app' updates images in org-buffer."
  (with-current-buffer (process-buffer proc)
    (when (and (boundp 'org-buf)
           (buffer-live-p org-buf))
      (with-current-buffer org-buf
    (org-display-inline-images)))))

(defcustom org-mouse-app-alist '((cygwin "cygstart" "-w") ;; option -w: wait for the application to finish
                 (gnu/linux "xdg-open")
                 (windows-nt "start")
                 (t "xdg-open"))
  "Rules for starting default applications.
Association list. Each element is a cons with the system type as `car'
and the list of the command and its first arguments.
The name of the file to be opened is appended to the list.
System type `t' stands for all systems not explicitly contained in the list."
  :type '(alist :key symbol :value (list string))
  :group 'org)

(defun org-mouse-app (event)
  "Start registered application for file at point."
  (interactive "e")
  (set-buffer (window-buffer (posn-window (event-end event))))
  (let* ((file (save-excursion
        (goto-char (posn-point (event-end event)))
        (substitute-in-file-name (nth 1 (org-link-at-point)))))
    (ext (file-name-extension file)))
    (unless (file-exists-p file)
      (let ((content (assoc-string ext org-mouse-app-templates t)))
    (when content
      (with-temp-buffer
        (insert (cdr content))
        (write-region (point-min) (point-max) file)
        ))))
    (select-window (posn-window (event-end event)))
    (let ((proc (apply 'start-process (append (list (concat "App:" file)
                            (concat " *App:" file))
                          (cdr (or (assoc-string system-type org-mouse-app-alist)
                               (assoc-string t org-mouse-app-alist)))
                          (list (expand-file-name (encode-coding-string (file-name-sans-versions file t)
                                                (or file-name-coding-system
                                                default-file-name-coding-system)
                                                'nocopy)))))))
      (when (string-match (image-file-name-regexp) file)
    (let ((current-buf (current-buffer)))
      (with-current-buffer (process-buffer proc)
        (setq-local org-buf current-buf)
        (set-process-sentinel proc #'org-mouse-app-update-images)))))))

(defun org-link-at-point ()
  "Return list (type path link) of org-link at point."
  (interactive)
  (let (type path link line search (pos (point)))
    (catch 'match
      (save-excursion
    (skip-chars-forward "^]\n\r")
    (when (org-in-regexp org-bracket-link-regexp)
      (setq link (org-link-unescape (org-match-string-no-properties 1)))
      (while (string-match " *\n *" link)
        (setq link (replace-match " " t t link)))
      (setq link (org-link-expand-abbrev link))
      (cond
       ((or (file-name-absolute-p link)
        (string-match "^\\.\\.?/" link))
        (setq type "file" path link))
       ((string-match org-link-re-with-space3 link)
        (setq type (match-string 1 link) path (match-string 2 link)))
       (t (setq type "thisfile" path link)))
      (throw 'match t)))

      (when (get-text-property (point) 'org-linked-text)
    (setq type "thisfile"
          pos (if (get-text-property (1+ (point)) 'org-linked-text)
              (1+ (point)) (point))
          path (buffer-substring
            (previous-single-property-change pos 'org-linked-text)
            (next-single-property-change pos 'org-linked-text)))
    (throw 'match t))

      (save-excursion
    (when (or (org-in-regexp org-angle-link-re)
          (org-in-regexp org-plain-link-re))
      (setq type (match-string 1) path (match-string 2))
      (throw 'match t)))
      (save-excursion
    (when (org-in-regexp (org-re "\\(:[[:alnum:]_@:]+\\):[ \t]*$"))
      (setq type "tags"
        path (match-string 1))
      (while (string-match ":" path)
        (setq path (replace-match "+" t t path)))
      (throw 'match t)))
      (when (org-in-regexp "<\\([^><\n]+\\)>")
    (setq type "tree-match"
          path (match-string 1))
    (throw 'match t)))
    (unless path
      (error "No link found"))
    (list type (substring-no-properties path) (substring-no-properties link))))

Leave a Comment

Your email address will not be published. Required fields are marked *

web tasarım