« El Capitan各種検証結果 | トップページ | メモ.appインポートAppleScript Sierra対応版 »

2015年10月 6日 (火)

メモ.appインポートAppleScript El Capitan対応版

以前、OS X 標準装備の メモ.app にテキストファイルをインポートする Apple Script を作った(「メモ.appインポートAppleScriptを作ってみた」)が、このスクリプトは El Capitan には対応していない。

(その理由は、各メモに指定したテキストを set body of note "foo bar" to "body text" という形で貼り付けることができなくなったことにある)

そこで今回、El Capitan 対応版を作成したが、この新しいスクリプトには問題があり、インポートすると「一行目がタイトル行、二行目が空白行、三行目からがインポートされたテキスト」という形になってしまう(つまり、一行目と三行目が重複する上、二行目に余分な空白行ができる)のである。

ただ、テキストをとにかくインポートして メモ.app 上で見たり編集したりできるようにするという目的では、さほど大きな問題ではないと思われるので、とりあえず暫定的に掲載しておくことにした。

使用は自己責任でお願いします。

なお、使用方法は記事の最後に掲載している。


 (*
 El Capitan 暫定対応版。
 
 メモ.app にテキストファイルの内容をインポートするスクリプト。
 指定した区切り文字列でテキストファイルを分割してそれぞれを1つのメモとしてインポートする。
 
 なお、当スクリプトは「スクリプトエディタ.app」上で改行コードなどをエスケープした状態で表示している(「スクリプトエディタ.app」の環境設定の「編集」タブで「フォーマット:文字列中のタブや改行をエスケープ」がチェックされているという前提)
 
 既知の問題:インポートしたテキストの一行目がそのままタイトルにはならず、その前にタイトル行と空白行が追加された形でインポートされてしまう
 *)
 
 tell application "Notes"
   set folderList to name of every folder of account "iCloud"
   --「メモ」フォルダーの実体は Notes という名前なので、考慮する
   set modified_folderList to {}
   repeat with fL in folderList
     if (fL as text) = "Notes" then set fL to "メモ"
     if (fL as text) = "false" then set fL to "false\t" --falseというフォルダー名だとキャンセルされてしまうので回避
     set the end of modified_folderList to fL
   end repeat
   
   set folderName to (choose from list modified_folderList with prompt "テキストファイルの内容を分割して、「メモ」アプリ内のフォルダにインポートします。\n\nまず「メモ」アプリ内のフォルダの名前を指定してください。")
   set folderName to (folderName as text)
   if folderName is "false" then error number -128 --キャンセルボタンを押した場合の処理
   if folderName is "false\t" then set folderName to "false"
   if folderName is "メモ" then set folderName to "Notes"
   
   repeat
     set textImported to choose file of type {"txt"} with prompt "インポートするテキストファイルを指定してください。"
     tell application "Finder"
       set textImported_name to name of textImported --あとで表示する
     end tell
     
     set textImported to POSIX path of textImported
     --改行コードが CRLF  LF かもしれないテキストを読み込み、CR に統一する。
     set textContents to do shell script "perl -pe 's/(\r)\n/$1/g; s/\n/\r/g;' < " & quoted form of textImported without altering line endings
     
     --HTMLタグを考慮
     set textContents to my replace_text(textContents, "&", "&amp;")
     set textContents to my replace_text(textContents, "<", "&lt;")
     set textContents to my replace_text(textContents, ">", "&gt;")
     --改行を変換しておく
     set textContents to my replace_text(textContents, "\r", "<br>")
     
     if length of textContents > 1000000 then
       display dialog "大きなファイルをインポートしようとしています。インポートに時間がかかるかもしれません。続けますか?" buttons {"中止する", "やり直す", "続ける"} default button 3
       set bReturned2 to button returned of result
       if bReturned2 is "中止する" then
         error number -128
       else if bReturned2 is "続ける" then
         exit repeat
       end if
     else
       exit repeat
     end if
   end repeat
   
   repeat
     display dialog "テキストファイルを分割するための「区切り文字列」を指定してください。\n\n改行は<br>、タブは<tab>と記述してください。\n\n空白の場合、分割せずにそのままインポートします。" default answer ""
     set divMarker to text returned of result
     if divMarker is "" then
       display dialog "区切り文字列が入力されていません。分割せずにインポートしますか?" buttons {"入力をやり直す", "分割しない"} default button 2
       set bReturned2 to button returned of result
       if bReturned2 is "分割しない" then
         set textParts to {textContents}
         exit repeat
       end if
     else
       set divMarker to my replace_text(divMarker, "<tab>", "\t")
       set tmp to AppleScript's text item delimiters
       set AppleScript's text item delimiters to divMarker --区切り文字列を設定
       set textParts to every text item of (textContents as text)
       set AppleScript's text item delimiters to tmp
       
       if length of textParts < 2 then
         display dialog "入力された区切り文字列は、読み込まれたテキストファイルに含まれていないようです。" buttons {"入力をやり直す"} default button 1
       else if length of textParts > 50 then
         display dialog "入力された区切り文字列では50以上に分割されます。区切り文字列を正しく入力しましたか?\n\nこのまま続けるかどうか選択してください。" buttons {"続ける", "入力をやり直す"} default button 2
         set bReturned3 to button returned of result
         if bReturned3 is "続ける" then
           exit repeat
         end if
       else
         exit repeat
       end if
     end if
   end repeat
   
   display dialog "最終確認です。\n\n「" & folderName & "」フォルダに「" & textImported_name & "」をインポートします。"
   
   set importCount to 0
   repeat with i in reverse of textParts
     
     set tmp_i to (i as text)
     set tmp_i to my replace_text(tmp_i, "<br>", "")
     set tmp_i to my replace_text(tmp_i, "\t", "")
     set tmp_i to my replace_text(tmp_i, " ", "")
     set tmp_i to my replace_text(tmp_i, " ", "")
     --分割されて出来たパーツが空白、もしくは改行やタブやスペースのみの場合は除外する
     if tmp_i is not equal to "" then
       set tmp2 to AppleScript's text item delimiters
       set AppleScript's text item delimiters to "<br>"
       set aParts to every text item of (i as text)
       set AppleScript's text item delimiters to tmp2
       
       --一行目を各メモのタイトルにする。一行目が空白、もしくはタブやスペースのみの場合は二行目以降をタイトルにする
       set title to "新規メモ"
       set pLength to length of aParts
       repeat with apCount from 1 to pLength
         set tmpPart to item apCount of aParts
         set tmpPart to my replace_text(tmpPart, "\t", "")
         set tmpPart to my replace_text(tmpPart, " ", "")
         set tmpPart to my replace_text(tmpPart, " ", "")
         if (tmpPart as text) is not "" then
           set title to item apCount of aParts
           exit repeat
         end if
       end repeat
       
       --「メモ」アプリの各メモの内容は実体としては(改行コードが全くない)HTML なので、以下で変換する。
       set bodyText to ""
       repeat with ap in aParts
         --行が空白、もしくはタブやスペースのみの場合は<br>を追加する
         set ap_tmp to ap
         set ap_tmp to my replace_text(ap_tmp, "\t", "")
         set ap_tmp to my replace_text(ap_tmp, " ", "")
         set ap_tmp to my replace_text(ap_tmp, " ", "")
         if (ap_tmp is "") then
           set np to "<div>" & ap & "<br></div>\n"
         else
           set np to "<div>" & ap & "<br></div>\n"
         end if
         set bodyText to bodyText & np
       end repeat
       
       --各メモを作成すると、普通は一行目が自動的にメモのタイトルになるが、
       --スクリプトで作成するとそうならないので、タイトルを付けなければならない。
       --メモの一行目が長い場合、そのままではタイトルまで長くなってしまうため、適宜短縮する。
       
       set wn to the number of words of title
       if wn > 15 then
         set title to text from word 1 to word 15 of title
       end if
       
       make new note in folder folderName of account "iCloud" with properties {body:bodyText, name:title}
       
       set importCount to importCount + 1
     end if
   end repeat
   display dialog "完了しました。\n\n" & importCount & "件のメモをインポートしました。" buttons {"終了"} default button 1
 end tell
 
 on replace_text(obj_text, search_str, replace_str)
   set astid_tmp to AppleScript's text item delimiters
   set AppleScript's text item delimiters to search_str
   set astid_texts to every text item of obj_text
   set AppleScript's text item delimiters to replace_str
   set obj_text to astid_texts as string
   set AppleScript's text item delimiters to astid_tmp
   return obj_text
 end replace_text


次に、このスクリプトが実際にどのように動くかについて述べる。

今ここに以下のようなテキストファイルがあるとする (文字コードは unicode でも Shift JIS でも かまわない)。

[smile.txt]
ハッピー
みゆき
-----
サニー
あかね
-----
ピース
やよい
-----
マーチ
なお
-----
ビューティー
れいか

まずメモ.app 内に「スマイル」というフォルダーを作る。そして上記のスクリプトを実行する。実行中にフォルダー名を訊かれるので「スマイル」と入力する。そして、インポートするファイルを選択するように指示されたら、このテキストファイルを指定する。最後に区切り文字列を訊かれたら「-----<br>」と入力する。

最終確認ボタンを押すと、メモ.app の「スマイル」フォルダー内に、「ハッピー」「サニー」「ピース」「マーチ」「ビューティー」という五つのメモが作成される。


« El Capitan各種検証結果 | トップページ | メモ.appインポートAppleScript Sierra対応版 »

コメント

コメントを書く

(ウェブ上には掲載しません)

« El Capitan各種検証結果 | トップページ | メモ.appインポートAppleScript Sierra対応版 »