[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/org-mime 484bf3b0b8 083/118: can edit mail-body in org-mod
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/org-mime 484bf3b0b8 083/118: can edit mail-body in org-mode buffer directly |
Date: |
Wed, 5 Jan 2022 07:58:49 -0500 (EST) |
branch: elpa/org-mime
commit 484bf3b0b8af461805b9e30d175510c031bcfbc3
Author: Chen Bin <chenbin.sh@gmail.com>
Commit: Chen Bin <chenbin.sh@gmail.com>
can edit mail-body in org-mode buffer directly
---
README.org | 23 ++++----
org-mime.el | 181 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 187 insertions(+), 17 deletions(-)
diff --git a/README.org b/README.org
index a36df1fdf0..f53ebdec95 100644
--- a/README.org
+++ b/README.org
@@ -1,4 +1,4 @@
-* org-mime v0.1.7
+* org-mime v0.2.0
[[https://travis-ci.org/org-mime/org-mime][https://travis-ci.org/org-mime/org-mime.svg?branch=master]]
[[http://melpa.org/#/org-mime][file:http://melpa.org/packages/org-mime-badge.svg]]
[[http://stable.melpa.org/#/org-mime][file:http://stable.melpa.org/packages/org-mime-badge.svg]]
@@ -24,12 +24,15 @@ Screenshot:
#+end_src
* Usage
** =M-x org-mime-htmlize=
-=M-x org-mime-htmlize= from within a mail composition buffer to export either
the entire buffer or just the active region to html, and embed the results into
the buffer as a text/html mime section.
+Run =M-x org-mime-htmlize= from within a mail composition buffer to export
either the entire buffer or just the active region to html, and embed the
results into the buffer as a text/html mime section.
Export a portion of an email body composed using =mml-mode= to html using
=org-mode=. If called with an active region only export that region, otherwise
export the entire body.
Warning: There has been some concern voiced over the potential complexity of
email resulting from calling this function on an active region resulting in
multiple =multipart/alternative= sections in the same email. Please see
[[http://thread.gmane.org/gmane.emacs.orgmode/23617][this email thread]] for a
discussion of the potential pitfalls of this approach. Speaking from personal
experience this has not been a problem for the author.
+You could use =org-mime-edit-mail-in-org-mode= edit mail in a special editor
with =org-mode=.
+
+After =org-mime-htmlize=, you can always run
=org-mime-revert-to-plain-text-mail= restore the original plain text mail.
** =M-x org-mime-org-buffer-htmlize=
=org-mime-org-buffer-htmlize= can be called from within an Org-mode buffer to
export either the whole buffer or the narrowed subtree or active region to
HTML, and open a new email buffer including the resulting HTML content as an
embedded mime section.
@@ -50,14 +53,14 @@ The following key bindings are suggested, which bind the
C-c M-o key sequence to
but works on subtree. It can also read subtree properties MAIL_SUBJECT,
MAIL_TO, MAIL_CC, and MAIL_BCC. Here is the sample of subtree:
#+begin_example
-* mail one
- :PROPERTIES:
- :MAIL_SUBJECT: mail title
- :MAIL_TO: person1@gmail.com
- :MAIL_CC: person2@gmail.com
- :MAIL_BCC: person3@gmail.com
- :END:
-content ...
+ * mail one
+ :PROPERTIES:
+ :MAIL_SUBJECT: mail title
+ :MAIL_TO: person1@gmail.com
+ :MAIL_CC: person2@gmail.com
+ :MAIL_BCC: person3@gmail.com
+ :END:
+ some text here ...
#+end_example
* Tips
** Embed image into mail body
diff --git a/org-mime.el b/org-mime.el
index 96cb352359..1a5bcc6132 100644
--- a/org-mime.el
+++ b/org-mime.el
@@ -6,7 +6,7 @@
;; Maintainer: Chen Bin (redguardtoo)
;; Keywords: mime, mail, email, html
;; Homepage: http://github.com/org-mime/org-mime
-;; Version: 0.1.7
+;; Version: 0.2.0
;; Package-Requires: ((emacs "25.1") (cl-lib "0.5"))
;; This file is not part of GNU Emacs.
@@ -67,8 +67,11 @@
;;
;; Quick start:
;; Write a message in message-mode, make sure the mail body follows
-;; org format. Before sending mail, run `M-x org-mime-htmlize' to convert the
-;; body to html, then send the mail as usual.
+;; org format. Run `org-mime-edit-mail-in-org-mode' to edit mail
+;; in a special edit with `org-mode'.
+;; Run `org-mime-htmlize' to convert the plain text mail to html mail.
+;; Run `org-mime-revert-to-plain-text-mail' if you want to restore to
+;; plain text mail.
;;
;; Setup (OPTIONAL):
;; You might want to bind this to a key with something like the
@@ -183,6 +186,13 @@ buffer holding the text to be exported.")
(defvar org-mime-debug nil
"Enable debug logger.")
+;; internal variables
+(defvar org-mime-src--overlay nil)
+(defvar org-mime-src--beg-marker nil)
+(defvar org-mime-src--end-marker nil)
+(defvar org-mime--saved-temp-window-config nil)
+(defconst org-mime-src--hint "## org-mime hint: Press C-c C-c to commit
change.\n")
+
(defun org-mime-get-export-options (subtreep)
"SUBTREEP is t if current node is subtree."
(cond
@@ -425,6 +435,13 @@ CURRENT-FILE is used to calculate full path of images."
(mml-attach-file f))
files))))
+(defun org-mime-mail-body-begin ()
+ "Get begin of mail body."
+ (save-excursion
+ (goto-char (point-min))
+ (search-forward mail-header-separator)
+ (+ (point) 1)))
+
;;;###autoload
(defun org-mime-htmlize ()
"Export a portion of an email to html using `org-mode'.
@@ -434,10 +451,7 @@ If called with an active region only export that region,
otherwise entire body."
(let* ((region-p (org-region-active-p))
(html-start (funcall org-mime-find-html-start
(or (and region-p (region-beginning))
- (save-excursion
- (goto-char (point-min))
- (search-forward mail-header-separator)
- (+ (point) 1)))))
+ (org-mime-mail-body-begin))))
(html-end (or (and region-p (region-end))
;; TODO: should catch signature...
(point-max)))
@@ -610,6 +624,159 @@ Following headline properties can determine the mail
headers,
(org-mime-compose exported file to subject other-headers t))
(message-goto-to)))))
+(defun org-mime-src--remove-overlay ()
+ "Remove overlay from current source buffer."
+ (message "org-mime-src--remove-overlay called overlay=%s p=%s"
org-mime-src--overlay (overlayp org-mime-src--overlay))
+ (when (overlayp org-mime-src--overlay)
+ (delete-overlay org-mime-src--overlay)))
+
+(defun org-mime-edited-code ()
+ "Get edited code."
+ (save-excursion
+ (goto-char (point-min))
+ (search-forward org-mime-src--hint (point-max) t)
+ (goto-char (line-beginning-position))
+ (buffer-substring-no-properties (point) (point-max))))
+
+(defun org-mime-edit-src-save ()
+ "Save parent buffer with current state source-code buffer."
+ (interactive)
+ (set-buffer-modified-p nil)
+ (let* ((edited-code (org-mime-edited-code))
+ (beg org-mime-src--beg-marker)
+ (end org-mime-src--end-marker)
+ (overlay org-mime-src--overlay))
+ (with-current-buffer (marker-buffer org-mime-src--beg-marker)
+ (undo-boundary)
+ (goto-char beg)
+ ;; Temporarily disable read-only features of OVERLAY in order to
+ ;; insert new contents.
+ (delete-overlay overlay)
+ (delete-region beg end)
+ (let* ((expecting-bol (bolp)))
+ (insert edited-code)
+ (when (and expecting-bol (not (bolp))) (insert "\n")))
+ (save-buffer)
+ (move-overlay overlay beg (point))))
+ ;; `write-contents-functions' requires the function to return
+ ;; a non-nil value so that other functions are not called.
+ t)
+
+(defun org-mime-src-mode-configure-edit-buffer ()
+ (add-hook 'kill-buffer-hook #'org-mime-src--remove-overlay nil 'local)
+ (setq buffer-offer-save t)
+ (setq-local write-contents-functions '(org-mime-edit-src-save)))
+
+(defvar org-mime-src-mode-hook nil
+ "Hook run after switching embedded org code to its `org-mode'.")
+
+(defun org-mime-edit-src-exit ()
+ "Kill current sub-editing buffer and return to source buffer."
+ (interactive)
+ (let* ((beg org-mime-src--beg-marker)
+ (end org-mime-src--end-marker)
+ (edit-buffer (current-buffer))
+ (source-buffer (marker-buffer beg)))
+ (org-mime-edit-src-save)
+ (unless source-buffer (error "Source buffer disappeared. Aborting"))
+ ;; Insert modified code. Ensure it ends with a newline character.
+ (message "=====edit-buffer=%s" edit-buffer)
+ (kill-buffer edit-buffer)
+
+ ;; to the beginning of the block opening line.
+ (goto-char beg)
+
+ ;; Clean up left-over markers and restore window configuration.
+ (set-marker beg nil)
+ (set-marker end nil)
+ (when org-mime--saved-temp-window-config
+ (set-window-configuration org-mime--saved-temp-window-config)
+ (setq org-mime--saved-temp-window-config nil))))
+
+(defvar org-mime-src-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-c C-c") 'org-mime-edit-src-exit)
+ (define-key map (kbd "C-x C-s") 'org-mime-edit-src-save)
+ map))
+
+(define-minor-mode org-mime-src-mode
+ "Minor mode for org major mode buffers generated from mail body."
+ nil " OrgMimeSrc" nil
+ )
+(add-hook 'org-mime-src-mode-hook #'org-mime-src-mode-configure-edit-buffer)
+
+(defun org-mime-src--make-source-overlay (beg end)
+ "Create overlay between BEG and END positions and return it."
+ (let* ((overlay (make-overlay beg end)))
+ (overlay-put overlay 'face 'secondary-selection)
+ (let ((read-only
+ (list
+ (lambda (&rest _)
+ (user-error
+ "Cannot modify an area being edited in a dedicated buffer")))))
+ (overlay-put overlay 'modification-hooks read-only)
+ (overlay-put overlay 'insert-in-front-hooks read-only)
+ (overlay-put overlay 'insert-behind-hooks read-only))
+ overlay))
+
+(defun org-mime-edit-mail-in-org-mode ()
+ "Call a special editor to edit the mail body in `org-mode'."
+ (interactive)
+ ;; see `org-src--edit-element'
+ (cond
+ ((eq major-mode 'org-mode)
+ (message "This command is not for `org-mode'."))
+ (t
+ (setq org-mime--saved-temp-window-config (current-window-configuration))
+ (let* ((beg (copy-marker (org-mime-mail-body-begin)))
+ (end (copy-marker (point-max)))
+ (bufname "OrgMimeMailBody")
+ (buffer (generate-new-buffer bufname))
+ (overlay (org-mime-src--make-source-overlay beg end))
+ (text (buffer-substring-no-properties beg end)))
+
+ (setq org-mime-src--beg-marker beg)
+ (setq org-mime-src--end-marker end)
+ ;; don't use local-variable because only user can't edit multiple emails
+ ;; or multiple embedded org code in one mail
+ (setq org-mime-src--overlay overlay)
+
+ (save-excursion
+ (delete-other-windows)
+ (org-switch-to-buffer-other-window buffer)
+ (erase-buffer)
+ (insert org-mime-src--hint)
+ (insert text)
+ (goto-char (point-min))
+ (org-mode)
+ (org-mime-src-mode))))))
+
+(defun org-mime-revert-to-plain-text-mail ()
+ "Revert mail body to plain text "
+ (interactive)
+ (let* ((txt-sep "<#part type=text/plain")
+ (html-sep "<#part type=text/html>")
+ mail-beg
+ mail-text
+ txt-beg
+ txt-end)
+ (save-excursion
+ (goto-char (point-min))
+ (setq mail-beg (search-forward mail-header-separator (point-max) t))
+ (setq txt-beg (search-forward txt-sep (point-max) t))
+ (setq txt-end (search-forward html-sep (point-max) t)))
+ (cond
+ ((and mail-beg txt-beg txt-end (< mail-beg txt-beg txt-end))
+ ;; extract text mail
+ (setq mail-text (buffer-substring-no-properties txt-beg
+ (- txt-end (length
html-sep))))
+ ;; delete html mail
+ (delete-region mail-beg (point-max))
+ ;; restore text mail
+ (insert mail-text))
+ (t
+ (message "Can not find plain text mail.")))))
+
(provide 'org-mime)
;; Local Variables:
;; coding: utf-8
- [nongnu] elpa/org-mime 5f253f541c 037/118: only use export header when creating html, keep out of email, (continued)
- [nongnu] elpa/org-mime 5f253f541c 037/118: only use export header when creating html, keep out of email, ELPA Syncer, 2022/01/05
- [nongnu] elpa/org-mime c6e2b95664 047/118: clean code, ELPA Syncer, 2022/01/05
- [nongnu] elpa/org-mime 64a3f56651 041/118: (setq org-html-with-latex nil) sometimes useful #16, ELPA Syncer, 2022/01/05
- [nongnu] elpa/org-mime 10098b001c 049/118: Fix file attachments and equations and enhance emails from org-files, ELPA Syncer, 2022/01/05
- [nongnu] elpa/org-mime 1e792ef061 059/118: Merge pull request #28 from titaniumbones/fix-klipse-error, ELPA Syncer, 2022/01/05
- [nongnu] elpa/org-mime f610861858 063/118: htmlize current subtree, ELPA Syncer, 2022/01/05
- [nongnu] elpa/org-mime 9506727ca7 072/118: README, ELPA Syncer, 2022/01/05
- [nongnu] elpa/org-mime b189976217 076/118: fixed CI, ELPA Syncer, 2022/01/05
- [nongnu] elpa/org-mime 778f818ad3 078/118: Add ASCII text/plain export test, ELPA Syncer, 2022/01/05
- [nongnu] elpa/org-mime 9f84446038 082/118: make emacs 25 test pass, ELPA Syncer, 2022/01/05
- [nongnu] elpa/org-mime 484bf3b0b8 083/118: can edit mail-body in org-mode buffer directly,
ELPA Syncer <=
- [nongnu] elpa/org-mime 5980ccaace 080/118: fixed unit test, ELPA Syncer, 2022/01/05
- [nongnu] elpa/org-mime b129579986 087/118: Regexp search for sig sep, ELPA Syncer, 2022/01/05
- [nongnu] elpa/org-mime 30bb3e663d 117/118: Merge pull request #66 from skangas/gplv3, ELPA Syncer, 2022/01/05
- [nongnu] elpa/org-mime 4105d1bb9c 004/118: support Emacs 23.4, 24.3 24.4, 24.5, ELPA Syncer, 2022/01/05
- [nongnu] elpa/org-mime e9b0be2860 005/118: mails need NO TOC, ELPA Syncer, 2022/01/05
- [nongnu] elpa/org-mime 3a16180195 006/118: clean code according to org-mode review, ELPA Syncer, 2022/01/05
- [nongnu] elpa/org-mime 351b233a7e 018/118: Don't use obsoleted function, ELPA Syncer, 2022/01/05
- [nongnu] elpa/org-mime 44e7a78ffd 019/118: Fix for cl-lib, ELPA Syncer, 2022/01/05
- [nongnu] elpa/org-mime dfe41e05e2 012/118: Merge pull request #1 from acowley/subject, ELPA Syncer, 2022/01/05
- [nongnu] elpa/org-mime d3ae6df753 013/118: Merge pull request #2 from acowley/subtree, ELPA Syncer, 2022/01/05