hatena-mode を拡張してみた。
最近の Web 巡回スタイルと言えば、FEEDBRINGER で取得した RSS を読みながら、気になる記事を見付けたら MM/Memo に登録し、気が向けばコメントしてくというものです。
そのため、Web 巡回には emacs-w3m をめっきり使わなくなり、Firefox ばかりになってしまいました。
そして、Firefox ばかりだと hatena に書き込みする気がまったく起きないのでした。(MM/Memo でコメントを書くだけでも、その操作のし難さにはストレスを感じてしまいます。何であんなに重いんでしょうか……)
この「feed を読んで bookmark する」というスタイルを、Emacs から出来れば良いのですが、emacs-w3m は、流行の Ajax インタフェースを持つ site には役に立ちません。
Emacs 上で動作する RSS Reader は、以前に少し探したときには NewsTicker しか見付けられませんでした。
自分としては、これだとちょっと微妙なのです。
取り敢えず、RSS を読むのは Firefox で仕方ないとして、気になった記事について hatena に記述する気になるにはどうすれば良いかと考えたところ、MM/Memo に bookmark したら、それを emacs-w3m で開いて hatena-mode で記事を書く、というシーケンスくらいしか思い付きません。これだとアクションが多くなって余りよろしく無いのですが、その際、簡単に言及リンクが記述できれば、少しはその気になるかもしれません。
と言う訳で、
M-x hatena でバッファを開くときに、コマンドを実行したバッファが emacs-w3m のバッファで region を選択していれば、選択範囲の文字列を抽出して言及リンクを挿入する。
このとき、選択範囲内に anchor があれば、その anchor に設定されている url を利用し、無ければそのバッファが訪問している url を利用して言及リンクを生成する。
様にしてみました。
(defvar hatena-util-url nil) (defvar hatena-util-string nil) (defvar hatena-util-anchor nil) (require 'w3m) (defun hatena-util-pickup-reffer-anchor (&optional opt) (interactive "P") (let* ((start (if (or (and (boundp 'transient-mark-mode) transient-mark-mode (boundp 'mark-active) mark-active) ; for emacs (and (fboundp 'zmacs-activate-region) zmacs-region-active-p)) ; for xemacs (region-beginning))) (end (and start (region-end)))) (when (string= (symbol-name major-mode) 'w3m-mode) (setq hatena-util-string (buffer-substring start end)) (when start (save-excursion (goto-char (next-single-property-change start 'w3m-href-anchor)) (setq hatena-util-url (or (and (<= (point) end) (w3m-anchor)) w3m-current-url)))) (message hatena-util-url) (when (and hatena-util-url hatena-util-string) (setq hatena-util-anchor (concat "<a href=" hatena-util-url ">" hatena-util-string "</a>")))))) (defun hatena-util-insert-reffer-anchor () (interactive) (if hatena-util-anchor (insert hatena-util-anchor) (message "no anchor."))) (defun hatena-util-cite-reffer-anchor () (interactive) (if hatena-util-anchor (progn (insert ">|\n ") (hatena-util-insert-reffer-anchor) (insert "\n|<\n")) (message "no anchor.")))
ってな関数と変数を定義しておき、
(defadvice hatena (around hatena-disable-insert-template activate) (unless (boundp 'html-helper-build-new-buffer) (load "psgml-html")) (setq hatena-util-url nil hatena-util-string nil hatena-util-anchor nil) (let ((html-helper-build-new-buffer nil) (insert-flag nil)) (hatena-util-pickup-reffer-anchor) (when (memq hatena-today-buffer (buffer-list)) (setq insert-flag t)) ad-do-it (when insert-flag (goto-char (point-max)) (while (= (char-before) ?\n) (delete-char -1)) (insert "\n\n") (insert "*[] ") (goto-char (- (point) 2))) (when hatena-util-anchor (save-excursion (goto-char (point-max)) (insert "\n\n") (hatena-util-cite-reffer-anchor) (insert "\n")))))
と advice しています。
hatena-util-* という変数群は、当初、let () 内部で束縛するだけの local な変数としていたんですが、anchor を生成し、貼り付ける動作を、M-x hatena したとき以外にも利用できる様にしようと思い、独立した変数にしてみました。
hatena-util という prefix は、取り敢えず本家 hatena-mode.el で使われていないのでこの様に書きましたが、バッティングし易い名前なので注意しておいた方が良さそうです。 ;; いつも、こういう名付けで悩んでしまうんだよなあ。
さーて、使いものになるでしょうか。