iPadで作図しMacでいい感じにメモる
Table of Contents
コード書いたり読んだりするのはMacでやったほうが楽だし、図を書いたりするのはiPadが楽。ということでこの間をいい感じに繋いだ話。
今までの連携方法
今までは以下の手順で連携していた。それなりに面倒なので、気軽に図を書いて差し込むという気になれなかった。
- iPadのPaperというアプリで図を書く
- ShareからAirDropを使ってファイルを転送
- (ほとんどの場合キャンバスサイズいっぱいに図を書かないので)Previewで画像の切り出し
- メモ先(Emacs)にドラッグ&ドロップ
Catalinaの機能を利用した連携
macOS CatalinaからMacとiPadを連携させるSidecarと共に、MacとiOS1を連携するいくつかの便利機能が入った。 いずれもMac側から実行するとiPadのアプリが自動で起動する。そしてiPad側で編集が完了すると、Mac側にその結果が反映されるという動き。
- NotesへiPadから写真/ドキュメント/図/を挿入
- 公式メモアプリのNotes2で 右クリック > insert from iPhone or iPad > Take Photo/Scan Document/Add sketch
- 画像/PDFにiPadで書き込み
- Finderから画像/PDFを 右クリック > Quick Action > Markup
Notes以外でも連携したい
公式の機能も便利なんだけど、Notesだけだとコードのシンタックスハイライトとか機能が無さすぎるので常用できない。(つまりEmacs org-mode3つかいたい) また、iPadでの作図もPaper4というアプリが使いやすいのでこれを使いたい。何か良い方法がないかと考えていると、Appleデバイス間のクリップボード同期機能 を思い出した。
クリップボードを利用すれば、アプリケーションに縛られることなくiPad<->Mac間で連携できる。非常に便利5。
- iPadのPaperで図を書く
- ShareからCopyを選択
- MacのEmacsでペースト(ペースト時にhookして画像のみ書き込み部分をCrop)
実際の設定
Clipboardから画像を生成するところはpngpaste6、そして画像の余白自動切り抜きはImageMagicのmogrifyを利用している。 メイン処理自体はShellScriptなのでどのエディタからも同じように利用できるはずだ。
(defun org-insert-clipboard-image ()
"Generate png file from a clipboard image and insert a link with caption and org-download tag to current buffer."
(interactive)
(let* ((filename
(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)))
(let* ((output-buffer (generate-new-buffer "*Async Image Generator*"))
(proc (progn
(async-shell-command (concat "pngpastet " filename) output-buffer)
(get-buffer-process output-buffer))))
(if (process-live-p proc)
(set-process-sentinel proc #'org-display-inline-images)))
(insert (concat
;; DOWNLOADED tag allows you to delete an image by org-download-delete command.
"#+DOWNLOADED: clipboard @ "
(format-time-string "%Y-%m-%d %H:%M:%S\n#+CAPTION: \n")
"[[file:" filename "]]"))))
;; Do not pop-up async-image-generator buffer because it's annoying.
(add-to-list 'display-buffer-alist '("^*Async Image Generator*" . (display-buffer-no-window)))
(define-key org-mode-map (kbd "C-M-y") 'org-insert-clipboard-image)
#!/bin/bash -eu
img=${1%.*}
ext=${1##*.}
function cleanup () {
[ -f $img.tif ] && rm $img.tif
}
trap cleanup EXIT
pngpaste $img.tif && \
convert $img.tif $img.$ext && \
mogrify -fuzz 5% -trim +repage $img.$ext
echo "Success to generate $(basename $img.$ext)"
Paperからコピーした画像は、clipboardinfoを読んでも画像情報がのっていない。 そのせいか、pngpasteで直接pngを生成すると変色してしまう。よって、gifのように劣化せず、jpegのように透過無効化されないtifを経由するというworkaroundをとっている。 (tifそのままだと画像サイズがでかいのでNG)
既存の図にチョイ足しする
ドキュメントとかスライドを読んでいると、出てくる図に対して理解した内容を書き込みたいことがある。そんな場合は、標準のQuickAction > Markup を使って書き込んでいく。この時、画像のパスを手動で探してFinder開くのは面倒なのでこれも関数を定義しておく。
(defun org-image-open-in-finder()
(interactive)
(let* ((linkp (bounds-of-thing-at-point 'sentence))
(link (buffer-substring-no-properties (car linkp) (cdr linkp)))
(filename (replace-regexp-in-string "\\[\\[\\([^:]*:\\)?\\([^]]+\\)\\].*" "\\2" link)))
(shell-command (concat "open " (file-name-directory filename)))))
(define-key org-mode-map (kbd "C-M-l") 'org-image-open-in-finder)
直接QuickActionをEmacsから呼びたかったが、AutomaterあたりのLibraryにその手の関数がなかったので諦めた。なにか方法があれば教えてほしい。
.