以服務的方式讓 Evernote 可以 Preview Markdown

之前改了一個 everwatch.rb 可以在背景偵測 Evernote 內文的改變,讓 Marked 2 來做 markdown preview,但最近也不知道是不是更新了 Marked 2 (2.5.0),功能執行起來似乎有點異常:

原本運作的方式是用一個 infinite loop 一直 watch Evernote 有無更動,大約每兩秒把資料從 html 的格式轉成純 txt 格式寫進去,但 Marked 2 會出現一直重覆 loading 數次的現象,再加上 Marked 2 會一直從頭 scroll 到修改的地方,還蠻煩的,但原因也不太清楚是什麼。

後來覺得似乎也不需要這麼頻繁的 update 這個 preview 視窗,在內文區寫作的時候,其實也不會一直去看 preview 的結果,既然要修 bug,便改用 Mac 內建 Service 的方式,在需要 preview 的時候再用快速鍵來 trigger,設定方式如下:

1. 用 Automator 新增一個 Service

ew01_add_a_service

2. 拖入一個「執行 AppleScript」

3. 設定作用的程式和貼入程式碼,儲存 Service

ew02_paste_code

4. 指定快速鍵

ew03_set_hotkey

在『系統偏好設定 > 鍵盤 > 快速鍵 > 服務』中指定,因為先前有指定在 Evernote 中才有作用,不會影響到其他的程式。如此一來,當想要看看 Markdown render 出來的結果時,在 Evernote 中按下 Ctrl + Z 即可。

神祕現象

原本的 everwatch 是個 ruby script, 不過裡面還串了 AppleScript 和 shell script,所以這次改版也想簡化一下,縮成只有 AppleScript 和 shell script(好像也沒多簡嘛!不過很多功能要純用 AppleScript 來做真的很耗時間又冗長啊!)。

在 try 的過程中也發現了個神祕的現象:

  1. Marked 2 在檔案「一被修改」的時候就會馬上重新 render
  2. 用 pipeline redirect output 到檔案 (> 操作),似乎會先把檔案清空,再寫入資料

由上面兩點來看,如果直接把 pipeline 輸出到最終的檔案,Marked 2 render 出來的就會是個空檔案,因此只好先用一個暫存檔把處理過的文字存起來,再 mv 過去要顯示的檔案。而之前的 ruby 版本是用 ruby 自己的 file operation,所以在背後可能避免了這個問題。另一個可能的解法是用 AppleScript 來實作 file I/O,但會有一些小問題,而且也會讓 script 變得有點複雜,就不考慮這條路。

另外一個神祕現象是,記事的內容和用 AppleScipt 取得的 selection 似乎會有一小段的時間差,大約是 1–2 秒左右吧!所以如果一打完字就想馬上 update preview 視窗的話,會看到前幾秒的狀態,這可能跟整個 AppleScript 的底層機制有關,暫時沒什麼好方法。

之前的 ruby script 會需要考慮 Evernote 儲存資料的路徑,而且不同版本的 Evernote 還有不同的 path,就我目前遇到的,至少有下列兩種(而且非免費版的帳號似乎又不同了):

  1. ~/Library/Containers/com.evernote.Evernote/Data/Library/Application Support/com.evernote.Evernote/accounts/www.evernote.com/#{account}/content
  2. ~/Library/Application Support/com.evernote.Evernote/accounts/www .evernote.com/#{account}/content

用 service 來 trigger 就不需要 care 這個路徑,code 可以相對簡潔一點。

改用 Service 來 preview 主要是為了解決 Marked 2 的奇異行為,額外獲得的好處是,只會在需要的時候才做 file I/O,或許在心理上,會覺得比較不那麼傷 SSD 硬碟吧!XD