2005-06-19

quick-url でリンクを簡単に入力する |Emacs|HTML|Texinfo|RD|

[2005-05-05] に、abbrev を使ってリンクを簡単に入力する方法について書いた。今回はその発展版。

何がしたいか

abbrev を使う方法で不便なのは、省略文字と展開文字が一対一対応していること。例えば、google という省略文字は必ず <a href="http://www.google.co.jp/">Google</a> に展開される。HTML だけ書いているなら、これは望ましい動作で問題ない。でも、HTML 以外でも同じことがしたかったらどうか。例えばメールの中に Google への URL を書きたくなったら。Texinfo のソースに Google へのリンクを含めたくなったら。RD に (以下省略)。一対一対応だと対処できない。

こういう場合の解決策はいくつかある。モード別に abbrev を定義するとか、展開する形式に従ってプレフィックスやサフィックスを決めておくとか...。こういう方法だと URL 変わったら全部修正しなくちゃいけないから大変。

省略文字と URL は決まっているんだから、モード別に展開する形式を定義できればそれに越したことはない。というわけで、quickurl パッケージ。

quickurl

quickurl は、abbrev のように省略文字を URL に展開する GNU Emacs の標準パッケージ。省略文字と URL はリストで定義する。

("GNU" "http://www.gnu.org/")

GNU の後ろで M-x quickurl すると

<URL:http://www.gnu.org/>

という形に展開される。

なお、URL に続けてコメントを書くこともできる。正確な書式は次の通り。

(<省略文字> <URL> <コメント>)

省略文字と URL のリストは、quickurl-url-file (デフォールトは ~/.quickurls) の中に書く。ぼくの .quickurls はこんな感じ。

(
;; Emacs
 ("emacs"    "http://www.gnu.org/software/emacs/"   "GNU Emacs")
 ("xemacs"   "http://www.xemacs.org/"             "XEmacs")
; Elisp
 ("auctex"   "http://www.gnu.org/software/auctex/"  "AUCTeX")
 ("navi2ch"  "http://navi2ch.sourceforge.net/"      "Navi2ch")
 ("emacsw3m" "http://emacs-w3m.namazu.org/"     "Emacs-w3m")
 ("mew"      "http://www.mew.org/"                  "Mew")
 ("howm"     "http://howm.sourceforge.jp/index-j.html")
 ("sdic"     "http://namazu.org/~tsuchiya/sdic/")
 ("reftex"   "http://staff.science.uva.nl/~dominik/Tools/reftex/" "RefTeX")
 ("tcode"    "http://openlab.ring.gr.jp/tcode/"     "T-Code")
 ("xsymbol"  "http://x-symbol.sourceforge.net/"     "XSymbol")
 ("yatex"    "http://www.yatex.org/"                "YaTeX")
;; Search Engine
 ("ask"      "http://ask.jp/"                   "Ask Jeeves")
; Google
 ("google"   "http://www.google.co.jp/"         "Google")
 ("googlenews" "http://www.google.co.jp/nwshp?hl=ja&tab=wn&ie=UTF-8" "Google News")
; Yahoo
 ("yahoo"    "http://www.yahoo.co.jp/"          "Yahoo!")
; goo
 ("goo"      "http://www.goo.ne.jp/")
; infoseek
 ("infoseek" "http://www.infoseek.co.jp/"       "Infoseek")
;; Map
 ("yahoomap" "http://map.yahoo.co.jp/"          "Yahoo! 地図")
 ("goomap"   "http://map.labs.goo.ne.jp/"       "goo 地図")
 ("infoseekmap" "http://map.www.infoseek.co.jp/" "Infoseek 地図")
 ("livedoormap" "http://map.livedoor.com/map/scroll" "Livedoor 地図")
 ("googlemap" "http://maps.google.com/"         "Google Map")
 ("mapsearch" "http://map.search.ch/index.en.html" "map.search.ch")
以下略...
)

新しい URL の追加は、.quickurls を開いて追加・保存するだけ。.quickurls の修正は直ちに反映される (再ロードとかは不要)。

モード別展開用の設定

実は、このままじゃ abbrev の global 展開と同じ。少し手を加えなくちゃいけない。

quickurl は、展開形式を自分でカスタマイズできる。この機能を使わせてもらう。モードごとに展開形式を変えるには、次のコードを .emacs に追加する。

;; 好みのキーに設定
(define-key mode-specific-map "q" 'quickurl)

(setq quickurl-grab-lookup-function #'quickurl-current-word)
(defun quickurl-current-word ()
  (save-excursion
    (let ((beg (progn (skip-chars-backward "A-Za-z0-9-") (point)))
   (end (progn (skip-chars-forward  "A-Za-z0-9-") (point))))
      (buffer-substring-no-properties beg end))))

(setq quickurl-format-function #'quickurl-mode-format-function)
(eval-after-load "quickurl"
  '(progn
    (defun quickurl-mode-format-function (url-list)
       (let ((url  (quickurl-url-url         url-list))
      (desc (quickurl-url-description url-list)))
  (delete-region (point) (search-backward lookup))
  (cond
   ((memq major-mode '(nxml-mode sgml-mode xml-mode yahtml-mode))
    (format "<a href=\"%s\">%s</a>" url desc))
   ((memq major-mode '(rd-mode))
    (format "((<%s|URL:%s>))" desc url))
   (t url))))
))

上の設定では、C-c q で文字列を展開するようにした。

quickurl-mode-format-function がこの quick hack のキモ。今の所、nxml-mode, sgml-mode, xml-mode, yahtml-mode と rd-mode に対応している。HTML 入力用のモードでは

<a href="URL">コメント</a>

という形に、RD モードでは

((<コメント|URL:URL>))

それ以外のモードでは、URL だけが入力される。

quickurl-current-word を定義しているのは、デフォールトでは展開語の直前が日本語だったり、タグだったりすると quickurl がちゃんと動かないのに対応する為。

雑感

abbrev 機能は便利だけど、URL の展開には向いていない気がする。abbrev は略語展開なんだから、URL の入力まですべきではなかったのかも。今は、abbrev は略語展開、quickurl は URL の入力と分けて使ってる。例えば、clmemo は略語展開で「ChangeLog メモ」へ、quickurl で clmemo.el へのリンク という感じ。

ref

No comments:

Post a Comment