2011年4月18日月曜日

EmacsでS式を pretty print する関数

pp-eval-last-sexpなど、頭に"pp-"が付く関数を利用するとS式を分かりやすく表示できる("pp" は pretty print の略で、pp.el の中にいくつかの関数が定義されている)。

たとえば、Emacsの xml-parser を使ってこのブログのフィードXMLをS式に変換したとする。それを単純に表示すると、次のように一行に出力されてとても分かりにくい。

((feed ((xmlns . "http://www.w3.org/2005/Atom") (xmlns:openSearch . "http://a9.com/-/spec/opensearch/1.1/") (xmlns:georss . "http://www.georss.org/georss") (xmlns:thr . "http://purl.org/syndication/thread/1.0") (xmlns:gd . "http://schemas.google.com/g/2005") (xmlns:feedburner . "http://rssnamespace.org/feedburner/ext/1.0") (gd:etag . "W/\"DkQHRn8yfip7ImA9WhZRGUo.\"")) (id nil "tag:blogger.com,1999:blog-7510134520604525369") (updated nil "2011-04-17T02:18:57.196+09:00") (title nil "Technical Memorandum") (subtitle ((type . "html")) "備忘録") 以下略…

一方、 pp-* を使った場合には、次のように表示される。

((feed
  ((xmlns . "http://www.w3.org/2005/Atom")
   (xmlns:openSearch . "http://a9.com/-/spec/opensearch/1.1/")
   (xmlns:georss . "http://www.georss.org/georss")
   (xmlns:thr . "http://purl.org/syndication/thread/1.0")
   (xmlns:gd . "http://schemas.google.com/g/2005")
   (xmlns:feedburner . "http://rssnamespace.org/feedburner/ext/1.0")
   (gd:etag . "W/\"DkQHRn8yfip7ImA9WhZRGUo.\""))
  (id nil "tag:blogger.com,1999:blog-7510134520604525369")
  (updated nil "2011-04-17T02:18:57.196+09:00")
  (title nil "Technical Memorandum")
  (subtitle
   ((type . "html"))
   "備忘録")
  (link
   ((rel . "http://schemas.google.com/g/2005#feed")
    (type . "application/atom+xml")
    (href . "http://dminor11th.blogspot.com/feeds/posts/default")))
以下略…

だいぶ分かりやすくなりました。

上の例を作るために使用したプログラム

xml-parse-region が返すオブジェクトを、pp-to-string で整形。

;; wgetプロセスの番兵(process sentinel)を定義しておく
(defun wget-callback (process event)
  (switch-to-buffer (process-buffer process))
  (end-of-buffer)
  (save-excursion
    (insert (pp-to-string (xml-parse-region (point-min) (point-max))))))
=> wget-callback

;; 非同期プロセスとして wget を実行
;; バッファ *wget* に結果を出力
(let ((proc
       (start-process
        "wget"
        "*wget*"
        "/usr/local/bin/wget"
        "-qO-"
        "http://feeds.feedburner.com/TechnicalMemorandum?format=xml")))
  (set-process-coding-system proc 'utf-8-dos 'utf-8-dos)
  (set-process-sentinel proc 'wget-callback))
=> wget-callback

なお、外部プロセスとしてwgetを呼び出しているので、wgetがインストールされていない場合やパスが異なる場合は動かないと思われる。

0 件のコメント:

コメントを投稿