Nokogiri を使って Evernote の XML (ENML) を tDiary の Wiki スタイルへ変換する
Evernote のクライアントで tDiary の日記を書くために。 Evernote で作ったノートは、 ENML という XHTML のような XML 形式になっている。 これを tDiary の日記形式(Wikiスタイル)へ変換した。 ENML 形式のサンプルは EvernoteのAPI Overviewに書かれている。
ためしにPCのEvernoteクライアントで日記の下書きをしたところ、以下のようなデータになった。 <li>の部分はEvernoteクライアントの箇条書きを使ったところになる。 基本的にXHTMLライクな書式。
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"> <en-note style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"> テスト <div><br/></div> <div>* 箇条書き1-1</div> <div>* 箇条書き1-2</div> <div>* 箇条書き1-3</div> <div><br/></div> <ul> <li>箇条書き2-1</li> <li>箇条書き2-2</li> </ul> <div>段落</div>
一方、AndroidのEvernoteクライアントだとこうなる。 文字化けじゃないよ。
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"><en-note style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div>これはテスト日記です。<br/>改行テスト。<br/>* 箇条書き1<br/>* 箇条書き2<br/>段落続き。<br/><br/>新規段落。<br/><br/> pre<br/><br/>段落。<br/> pre<br/>段落。<br/><br/>* 箇条書き1<br/>* 箇条書き2<br/><br/>! セクション<br/><br/>テスト。</div></en-note>
こちらは1つのdiv要素の中に本文が丸ごと入っている。 テキスト(本文)は実体参照になり、改行は<br/>を使ってる。
このフォーマットをWikiスタイルに変換する。 以前なら REXML を使うんだけど、いまなら Nokigiri がよさそう。 頭から順番に変換していけばいいので、DOMよりSAX向き。
Module Nokogiri::XML::SAXを読んで、以下のようなスクリプトを作った。
# wiki_style_document.rb - WikiStyle document format for ENML # class WikiStyleDocument < Nokogiri::XML::SAX::Document attr_reader :text def start_document @text = '' end def start_element(name, attrs = []) case name when 'li' @text << '* ' when 'br' @text << "\n" end end def characters(string) @text << string end def to_s @text end end
以下のようにして変換できる。
parser = Nokogiri::XML::SAX::Parser.new(doc = WikiStyleDocument.new) parser.parse(xml) puts doc.text => これはテスト日記です。 改行テスト。 * 箇条書き1 * 箇条書き2 段落続き。 新規段落。 pre 段落。 pre 段落。 * 箇条書き1 * 箇条書き2
<br/>タグなら改行、<li>なら「* 」に変換する。 それ以外はそのまま。 最初は<div>を改行に変換しなければいけないと思ってたけど、元のENMLに改行が含まれているので、これで上手く行った。
SAXって初めて使うけど、以外と簡単だね。