今期も終わりましたね。
今期も終わりましたね。
org-modeには画像のリンクをインラインで表示する機能がある。
[[file:hoge.png]]
のようなリンクがあった場合に、org-toggle-inline-images ( C-C C-x C-v ) でインライン表示するかどうかをトグルで切り替えられる。
しかしこの機能はURLには対応していない。
[[http://www.google.co.jp/images/srpr/logo3w.png]]
のようなリンクがインラインで表示されないのである。
なので、それが出来るようにしてみた。
結果のソースコードはorg-http-inline-image.el。
まずはウェブ上からhttp経由で画像を取得する方法について調べた。
(insert-image (create-image (with-current-buffer (url-retrieve-synchronously "http://upload.wikimedia.org/wikipedia/commons/thumb/9/97/The_Earth_seen_from_Apollo_17.jpg/260px-The_Earth_seen_from_Apollo_17.jpg") (buffer-substring (re-search-forward "\n\n") (point-max))) nil t))
これで任意のURLから画像を取得できる。
url-retrieve-synchronouslyで画像データを含んだバッファを作成し、
HTTPヘッダを除いた部分を取り出してcreate-imageしているだけ。
試しにinsert-imageするとバッファに画像が表示されるはず。
本当は非同期にしたり画像をキャッシュしたりエラー処理をしないとダメなんだろうけど、まずは最低限のコードが知りたかったので。
あと、kill-bufferした方がメモリ的には良いのかもしれない。
画像のインライン表示はorg.el内のorg-display-inline-imagesで行っている。
この関数は7.8.03の時点では次のようになっている。
(defun org-display-inline-images (&optional include-linked refresh beg end) "Display inline images. Normally only links without a description part are inlined, because this is how it will work for export. When INCLUDE-LINKED is set, also links with a description part will be inlined. This can be nice for a quick look at those images, but it does not reflect what exported files will look like. When REFRESH is set, refresh existing images between BEG and END. This will create new image displays only if necessary. BEG and END default to the buffer boundaries." (interactive "P") (unless refresh (org-remove-inline-images) (if (fboundp 'clear-image-cache) (clear-image-cache))) (save-excursion (save-restriction (widen) (setq beg (or beg (point-min)) end (or end (point-max))) (goto-char (point-min)) (let ((re (concat "\[\[\(\(file:\)\|\([./~]\)\)\([^]n]+?" (substring (org-image-file-name-regexp) 0 -2) "\)\]" (if include-linked "" "\]"))) old file ov img) (while (re-search-forward re end t) (setq old (get-char-property-and-overlay (match-beginning 1) 'org-image-overlay)) (setq file (expand-file-name (concat (or (match-string 3) "") (match-string 4)))) (when (file-exists-p file) (if (and (car-safe old) refresh) (image-refresh (overlay-get (cdr old) 'display)) (setq img (save-match-data (create-image file))) (when img (setq ov (make-overlay (match-beginning 0) (match-end 0))) (overlay-put ov 'display img) (overlay-put ov 'face 'default) (overlay-put ov 'org-image-overlay t) (overlay-put ov 'modification-hooks (list 'org-display-inline-modification-hook)) (push ov org-inline-image-overlays)))))))))
この関数は、
といった動作をしている。
どうしたものか。
まず、httpリンクを見つけ出さなければならない。
正規表現部分の三つ目の開き括弧部分にhttpを入れることにした。
(let ((re (concat "\[\[\(\(file:\)\|\([./~]\|http://\)\)\([^]n]+?" (substring (org-image-file-name-regexp) 0 -2) "\)\]" (if include-linked "" "\]"))) old file path ov img) (while (re-search-forward re end t) (setq old (get-char-property-and-overlay (match-beginning 1) 'org-image-overlay)) (setq file (concat (or (match-string 3) "") (match-string 4))) (setq path (expand-file-name file))
httpの部分はファイル名に含めたかったので、二つ目では無く三つ目にした。
それに伴い変数fileはexpand-file-nameする前のファイル名にして、変数
pathはexpand後にしてある。
次に実際に画像を用意するところだが、このままだと少し見通しが悪い。
新しいオーバーレイを作る部分を別の関数に分離してみた。
(when (file-exists-p file) (if (and (car-safe old) refresh) (image-refresh (overlay-get (cdr old) 'display)) (setq img (save-match-data (create-image file))) (my-org-add-inline-image-overlay img)))))))) (defun my-org-add-inline-image-overlay (img) (when img (let ((ov (make-overlay (match-beginning 0) (match-end 0)))) (overlay-put ov 'display img) (overlay-put ov 'face 'default) (overlay-put ov 'org-image-overlay t) (overlay-put ov 'modification-hooks (list 'org-display-inline-modification-hook)) (push ov org-inline-image-overlays))))
少し見通しが良くなった。下半分はファイルでもURLでも共通の処理であり、問題は上半分だけとなった。
さて、ファイルへのリンクかURLへのリンクかによって処理を変えたいのだが、どうしたら良いだろうか。
問題の部分。
(when (file-exists-p file) (if (and (car-safe old) refresh) (image-refresh (overlay-get (cdr old) 'display)) (setq img (save-match-data (create-image file))) (my-org-add-inline-image-overlay img))))))))
このようにファイルの時の処理とURLと共通の処理が交互に現れていて分離するのが先ほどと比べて難しい。
ここはlambdaを使って共通の処理だけをくくりだしてみた。
(cond ((string= (match-string 3) "http://") (my-org-update-inline-image refresh (lambda () (save-match-data (my-org-create-image-from-url file))))) ((file-exists-p path) (my-org-update-inline-image refresh (lambda () (save-match-data (create-image path)))))))))) (defun my-org-update-inline-image (refresh loader) (let ((old (get-char-property-and-overlay (match-beginning 1) 'org-image-overlay))) (if (and (car-safe old) refresh) (image-refresh (overlay-get (cdr old) 'display)) (my-org-add-inline-image-overlay (funcall loader)))))
あとはURLから画像を読み込む関数が有れば良い。
(defun my-org-create-image-from-url (url) (let* ((buf (url-retrieve-synchronously url)) (res (if buf (with-current-buffer buf (buffer-string)))) (sep (if res (string-match "nn" res))) (data (if sep (substring res (+ 2 sep)))) (img (if data (create-image data nil t)))) (if buf (kill-buffer buf)) img))
nilチェックやkill-bufferで不要になったバッファを削除したりしている。
えー、アボガドソース、シーザーソース風、ですか。うーん、この微妙な苦みというかなんというか。不思議な味ですね。美味しいとは思わないな。
初めてネットプリントを使ってみた。Web上で表示された申込書を印刷するため。現在自宅にはプリンターが無いので。
PDF(XPSでも良いんだろうけど、何となくPDF)へ「印刷」して、出来たファイルをネットプリントのサイトからサーバーへ送信して登録完了。セブンイレブンのコピー機みたいなのに予約番号と20円を入れて印刷。
うん、これは良いものだ。前々から場所を取らないモバイルプリンターでも買おうかなと思ったいたのだけど、これでますます不要になった。
知り合いによると、お店のクーポン券をネットプリントに登録しておいて、必要になったらセブンイレブンで印刷したりといった使い方も出来るらしい。
他にも予約番号をtwitterで配布して手書き新聞を配布したり、ミニコミ誌を配布するのに使っている人もいるらしい。
AndroidやiPhoneのアプリもあるので、出先で写真を撮ってすぐに印刷ということも出来そうだ。
こういうメンタルな話は嫌いじゃ無いけど、ときどき挟まるおもしろ映像にはちょっと引いちゃうかな。
傷つかない心、欲しいですね。
東京MXで再放送をやっていたので、本放送以来に見た。
うわぁ……、可愛いな。
山本の件とか何となく覚えているから、話が良く理解できる。
それにしても実写映画のCMが……。三次元イラネ。
2013-08-12追記: elisp側で何とかするコードを書きました。複数の文字符号化方式が混在しているときのmagit文字化け対策コード
「 fatal: cannot handle encwrapper internally 」というエラーが出るのでgit-encwrapperを修正しました。
原因はどうやらexecvp(git_filename, argv)にあったようです。git_filenameがgitなのに対してargv<sup><a id="fnr.1" name="fnr.1" class="footref" href="#fn.1">1</a></sup>がgit-encwrapperであるとこのようなメッセージがexecvp呼び出し後のどこかで発生するようです。
ただし、execvpの呼び出し先がmsysgitの場合はこの問題は発生しませんでした。Cygwinのgitだと発生するようです。私はmsysgitを使っているのでこの問題に長らく気がつきませんでした。
なぜ気がついたかというと、Cygwinのgettext-devlパッケージがgitに依存するようになって、Cygwinのgitが自動的にインストールされてしまったからです。
さらにmsysgitとCygwinを連携させるために、ある種のトリックを使っていたことも問題をややこしくしました。msysgitのbinにパスを通すとmsysgit付属の各種UNIXコマンドにもパスが通ってしまって困ります。なので、msysgitにはパスを通さずにC:Program Files (x86)Gitbingit.exeを実行するだけの代理の実行ファイルを/usr/local/bin/git.exeとして配置していたのです(ちなみにハードリンクではexeと同じディレクトリにdllが無いのでうまくいきませんでした。dllも含めて/usr/local/binへ入れればうまくいったかもしれませんけど……)。そしてCygwinのbashからgitを実行したときはPATH=に先に/usr/loca/binが入っていたのでmsysgitが呼ばれ、NTEmacsから実行したときはPATH=に先に/usr/binが入っていたのでCygwinのgitが呼ばれるという無茶苦茶な状況に。なぜEmacs上からだけ動かないんだ!?と原因究明に手間取ってしまいました。結局Windowsの環境変数PATHの順番を調整することでなんとかなりました。
本当はCygwinのgitが使いたいのですが、Cygwinのgitはテキストマウントに対応していません。テキストマウントしたディレクトリにリポジトリを作ると、リポジトリ内の改行コードがcrlfになってしまい、fatalエラーで何も操作できなくなります。
DEFINITION NOT FOUND.
この間コンビニで粉末のインスタント緑茶を買うつもりが間違えて普通の緑茶葉を買ってしまいました。伊藤園のお~いお茶ブランドで少し抹茶が混じったタイプです。
緑茶は紐付きのお茶パックに入れて、マグカップの中で直接煎れて飲んでいます。パックは一番茶を入れたらすぐに水でゆすいでぎゅっと絞って水気を落としてゴミ箱へポイっです。水でゆすがないとやけどします。確実に飲むとわかっているなら別のコップにとっておいても良いですが、それでも二番茶までにとどめておきます。わざわざ時間が経って味が悪くなったものを飲む必要はありませんし、たいてい飲まずにそのまま放置されてしまいますので。
ティーバッグはあまり飲みません。定番は紅茶のティーバッグですが、コンビニで見かけるタイプは一人で飲むには数が多すぎます。また、バッグを紙の袋で包んでいるだけなので劣化が心配です。
この間セブンイレブンでほうじ茶ティーバッグを買いましたが、あれは一つ一つ袋で密閉してあって劣化しにくいようになっていました。ただ、ほうじ茶としての味は今ひとつでしたが。
ティーバッグと言えば、最近マクドナルドでドリンクを頼むときはホットミルクティーを頼みます。頼んだことがある人は知っていると思いますが、マクドナルドでホット(ミルク/レモン)ティーを頼むとリプトンのティーバッグ(Sなら1つ、Mなら2つ)とお湯が出てきます。これ、初めて頼む人はびっくりすると思いますが、まあ、マクドナルドはそういう店なので。アイスティーの方も結局はティーバッグですし。以前はコーヒーばかり頼んでいたのですが、近年はコーヒーが体にきつく感じられるようになってきて、かといって冬場に冷たい飲み物はいやなのでホットティーを頼むようになりました。