« メモ.appインポートAppleScript El Capitan対応版 | トップページ | macOS SierraのSpotlightによる日本語テキストの内容検索[更新] »

2016年9月21日 (水)

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

以前、macOS 標準装備の メモ.app にテキストファイルをインポートする Apple Script を作った(「メモ.appインポートAppleScriptを作ってみた」)が、Sierra には対応していないようなので、対応版を作成した。

(※Sierra のメモ.app にはインポート機能が備わっている(メニューバーの「ファイル」→「"メモ"に読み込む」)ため、このスクリプトを使う意味はあまりないかもしれないが、インポートするフォルダーを指定することができる、一つのテキストファイルを分割してインポートできるなどのメリットがあることはある)

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

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

(インポートではなく、エクスポート(書き出し)するためのスクリプトも以前作成したことがある。「メモ.appエクスポートAppleScriptを作った」を参照)

※注記:
macOS Sierra 10.12.0 の時点では下の画像の通り Apple Script の選択ダイアログボックスにバグがある

今後、10.12.1 以降で修正されるかもしれない。その場合はこの注記は無視していただきたい。

-- スクリプト次行から --

 (*
 メモ.app にテキストファイルの内容をインポートするスクリプト。
 指定した区切り文字列でテキストファイルを分割してそれぞれを1つのメモとしてインポートする。
 
 なお、当スクリプトは改行コードなどをエスケープした状態で表示している(「AppleScript エディタ」の環境設定の「編集」タブで「詳細:文字列中のタブや改行をエスケープ」がチェックされているという前提)
 *)
 
 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>"
         else
           set np to "<div>" & ap & "</div>"
         end if
         set bodyText to bodyText & np
       end repeat
       
       make new note in folder folderName of account "iCloud"
       
       set bodyText to "<html><head></head><body style=\"word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; \">" & bodyText & "</body></html>"
       set body of note "新規メモ" to bodyText
       
       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 の「スマイル」フォルダー内に、「ハッピー」「サニー」「ピース」「マーチ」「ビューティー」という五つのメモが作成される。


« メモ.appインポートAppleScript El Capitan対応版 | トップページ | macOS SierraのSpotlightによる日本語テキストの内容検索[更新] »

コメント

コメントを書く

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

« メモ.appインポートAppleScript El Capitan対応版 | トップページ | macOS SierraのSpotlightによる日本語テキストの内容検索[更新] »