エンジニアのソフトウェア的愛情

または私は如何にして心配するのを止めてプログラムを・愛する・ようになったか

JavaScriptでEvernoteを操作する、ただしYosemiteにかぎる

OS X が Yosemite になって、標準で JavaScript を扱えるようになりました。

使い方について、こちらの方が詳しくまとめられています。


JavaScriptAppleScript と同等のことができるというのなら。
以前このブログに書いたように AppleScriptEvernote を操作することができるのだら、JavaScript でも操作できるだろうと思い、やってみました。

ノートブックを作る


Evernote アプリケーションオブジェクトを取得し、createNote メソッドを呼ぶことでノートを作ることができます。

#!/usr/bin/osascript -l JavaScript

// アプリケーションオブジェクトを取得する
var evernote = Application('Evernote');

// 新しいノートを作る
// ノートブックは、なければノートと一緒に作られます
evernote.createNote({withText: '新しいテキスト', notebook: 'JSで作ったノート', title: 'JSで作りました'});


実行

$ chmod +x create_note 
$ ./create_note 
Application("Evernote").notebooks.byName("JSで作ったノート 1").notes.byId("x-coredata://B95C0294-C338-4778-937B-76D3050F2609/ENNote/p16263")

あるいは

$ osascript -l JavaScript create_note
Application("Evernote").notebooks.byName("JSで作ったノート").notes.byId("x-coredata://B95C0294-C338-4778-937B-76D3050F2609/ENNote/p16265")


あたりまえですが osascript コマンドで実行する場合は1行目の shebang は不要です。
スクリプトの言語の指定 -l JavaScript は大文字小文字まで一致させないとエラーになりました。
なお、ファイル明に拡張子 .js をつけると言語指定をしなくても JavaScript として実行してくれるようです。


osascript コマンドは、実行したスクリプトの最後の値を結果として表示します。このばあいは作成されたノートのオブジェクトが表示されます。x-coredata://〜 が作成されたノートの ID です。


ノートブックをしなかった場合デフォルトのノートブックにノートが作られます。また指定したノートブックがなかった場合にはノートが作成されるのと同時にノートブックも作られます。

withText の代わりに withHtml を使うと HTML でマークアップした内容のノートを作ることができます。


ノートを見つける

Evernote アプリケーションのオブジェクトには findNote というメソッドがあります。…あるのですが。
メソッドの仕様を見てみると*1引数に note link を取るようになっています。


具体的にはこんな感じ。

var evernote = Application('Evernote');
evernote.findNote('evernote:///view/1350007/s11/fa134265-f675-4278-a294-ed1a8df8a008/fa145665-f675-4278-a294-ed1a8ca8a008/');


つまり Evernote でノート間のリンクを作るための文字列を引数として渡す必要があります。

検索という用途で考えるとあまりうれしくありません。


そこでもう一つのメソッド findNotes を利用します。findNotes メソッドは引数に検索文字列を取ります。この文字列は Evernote でノートを検索するときの検索文字列とおなじです。

var evernote = Application('Evernote');
var notes = evernote.findNotes('notebook:JSで作ったノート intitle:JSで作りました');

for(var i in notes) {
  console.log('No.' + i + ' タイトル: ' + notes[i].title() + ' リンク: ' + notes[i].noteLink());
}

実行。

$ osascript find_note.js 
No.0 タイトル: JSで作りました リンク: evernote:///view/1350007/s11/fa134265-f675-4278-a294-ed1a8df8a008/fa145665-f675-4278-a294-ed1a8ca8a008/


検索文字列での検索ですから複数のノートがヒットする可能性があります。ピンポイントで一つのノートを得たいときは、一旦 findNotes メソッドで該当するノートを見つけ、ノートのプロパティ noteLink でリンクの文字列を取得しておいて、findNote メソッドでノートを取得する、といった感じになりそうです。


検索文字列については Evernote のサイトの「Evernote の高度な検索シンタックスの使い方 - Evernote ナレッジベース」を参照してみてください。


ノートを更新する

ノートの内容を更新するには3つの方法があります。

  • enmlContent プロパティに値を代入する
  • htmlContent プロパティに値を代入する
  • append メソッドで値を追加する

ENML というのは Evernote 固有のマークアップ形式のようです。まだ調べてませんが。

ENML 、 HTML でどのように格納されているかはプロパティの値を表示するとわかります。

var evernote = Application('Evernote');
var note = evernote.findNote('evernote:///view/1350008/s12/fa145665-f675-4278-a294-ed1a8ca8a008/fa145665-f675-4278-a294-ed1a8ca8a008/');

console.log('ENML: ' + note.enmlContent());
console.log('HTML: ' + note.htmlContent());


実行。

$ osascript show_note.js 
ENML: <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">
<en-note>新しいテキスト</en-note>

HTML: 
<div id="en-note">新しいテキスト</div>


プロパティに値を代入するとノートの内容を更新できます。

var evernote = Application('Evernote');
var note = evernote.findNote('evernote:///view/1350008/s12/fa145665-f675-4278-a294-ed1a8ca8a008/fa145665-f675-4278-a294-ed1a8ca8a008/');

console.log('before: ' + note.htmlContent());

note.htmlContent = '更新したテキスト'

console.log('after: ' + note.htmlContent());


実行。

$ osascript update_note.js 
before: 
<div id="en-note">新しいテキスト</div>

after: <div id="en-note">
更新したテキスト
</div>


これで確かに更新できるのですが。ですが。
わたしの環境ではこのスクリプトを続けて実行しようとするとエラーになります。原因はまだ調べていません。

 $ osascript update_note.js 
before: <div id="en-note">
更新したテキスト
</div>
update_note.js:225:254: execution error: Error on line 6: Error: この操作により月間アップロード許容量を超過します。 (1)


これを次のようにすると更新できるようになります。理由はまだ調べていません。

var evernote = Application('Evernote');
var note = evernote.findNote('evernote:///view/1350008/s12/fa145665-f675-4278-a294-ed1a8ca8a008/fa145665-f675-4278-a294-ed1a8ca8a008/');

console.log('before: ' + note.htmlContent());

note.htmlContent = ''
note.append({text: '更新したテキスト'})

console.log('after: ' + note.htmlContent());

実行。

$ osascript update_note.js 
before: <div id="en-note">
更新したテキスト
</div>
after: <div id="en-note">
 更新したテキスト</div>


また append メソッドの説明をみると次のようになっています。

append&#8194;method : Append data to an existing note. You must specify exactly one of 'text', 'html', or 'attachment' parameters.
  append Note : The note to modify.
    [text: text] : Text to append.
    [html: text] : HTML to append.
    [attachment: file] : Attachment file to append.


text の代わりに html を利用すれば HTML のマークアップで装飾ができます。

var evernote = Application('Evernote');
var note = evernote.findNote('evernote:///view/1350008/s12/fa145665-f675-4278-a294-ed1a8ca8a008/fa145665-f675-4278-a294-ed1a8ca8a008/');

console.log('before: ' + note.htmlContent());

note.htmlContent = ''
note.append({html: '<font color=red>更新</font>したテキスト'})

console.log('after: ' + note.htmlContent());

実行結果。


いつか読むはずっと読まない:ただの虫

2012年の刊行ですが先日存在を知り購入。15年ぶりの新刊だそうで。

パラダイスバード (BUNCH COMICS)

パラダイスバード (BUNCH COMICS)


先の2作品も新装版が出ていたみたいですね。

楽園通信社綺談 (キュンコミックス)

楽園通信社綺談 (キュンコミックス)

ビブリオテーク・リヴ (キュンコミックス)

ビブリオテーク・リヴ (キュンコミックス)

*1:スクリプトエディタを起動し、メニューから「ファイル > 用語説明を開く... 」を選択します。アプリケーションを選択するダイアログが開くので Evernote を選択すると用語説明のウィンドウが表示されます。言語を JavaScript に設定することで JavaScript で呼び出せる形式でメソッドが表示されるようになります。