Archive for the 'NSAttributedString' Category

2017/09/13 Safariの最前面のウィンドウの内容をすべて取得してTextEditで新規ドキュメントを作成

Safariで表示中の最前面のウィンドウのURLを取得して本文文字列を抽出し、テキストエディットの新規書類としてオープンするAppleScriptです。

たまに、Blog上の情報を部分的に利用したいようなときに、テキスト内容をコピー&ペーストで別のアプリケーションに持ってきますが、たまにテキストの選択ができないBlogに遭遇することがあります。

こんなとき、SafariのAppleScript用語辞書にはdocumentからtextが取得できるということになっていますが、目下Safari 10.1.2上のこの機能にはアクセスできません。SafariのAppleScript用語辞書はSafari 10.xになってからdocumentのpropertiesが取得できない(エラーになる)など、いまひとつです。

さらに、もっと前からdocumentのtextが取得できないようになっているので、とりあえずバグレポートで文句を書きつつ、対処してみました(Appleがバグ修正するのを待つよりも自前でScript書いた方が早いという)。

Safariの最前面のウィンドウ(frontmost document)から表示中のURLだけ取得してくれば、AppleScript単体でWeb内容のダウンロードからテキストの抽出までできるので、そのとおりに処理。取得しただけだとスクリプトエディタ上でログ表示(コピー可)するだけなので、とりあえずテキストエディットの新規書類を作成してその本文にテキストを入れてみました。

ちなみに、本Blog掲載のプログラムリストの末尾に「スクリプトエディタに内容を転送するリンク」をつけていますが、これはコピー&ペーストではなく、カスタムURLプロトコル(applescript://)経由でプロセス間通信によりWebブラウザからスクリプトエディタにデータ転送する仕組みを利用しています。一般ユーザーにとっては、「コピー&ペーストではない」という点がなかなか理解できないようです。

AppleScript名:Safariの最前面のウィンドウの内容をすべて取得してTextEditで新規ドキュメントを作成
– Created 2017-09-09 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
–http://piyocast.com/as/archives/4823

property NSAttributedString : a reference to current application’s NSAttributedString
property NSData : a reference to current application’s NSData
property |NSURL| : a reference to current application’s |NSURL|

–Get URL from frontmost window (document)
tell application “Safari”
  if (every document) = {} then return
  
tell front document
    set aURLstr to URL
  end tell
end tell

–Get String from Safari URL
set sRes to getStringFromRemoteHTML(aURLstr) of me

–Make new document with TextEdit to browse or edit text contents
tell application “TextEdit”
  make new document with properties {text:sRes}
  
activate
end tell

on getStringFromRemoteHTML(aURLstr as string)
  set theURL to |NSURL|’s URLWithString:aURLstr
  
set theData to NSData’s dataWithContentsOfURL:theURL
  
set attStr to NSAttributedString’s alloc()’s initWithHTML:theData documentAttributes:(missing value)
  
if attStr = missing value then error “Internet Connection lost or Wrong URL”
  
return (attStr’s |string|()) as string
end getStringFromRemoteHTML

★Click Here to Open This Script 

2017/09/10 HTMLをplain textに変換 v2

HTMLのファイルをplain textに変換するAppleScriptです。

前バージョンでは、,△蕕じめHTMLを変数に読み込んでおいて、△修離如璽燭NSString経由でNSAttributedStringに(文字エンコーディングを指定しつつ)読み込んでいました。

このため、,涼奮で文字コードエンコーディングの判定がうまく行かないと、正しいPlain Textが得られないという「弱点」がありました(一応、対策のためにテキストエディタ並みの日本語テキストエンコーディング自動判定ライブラリを併用していますが、毎回掲載するわけにもいきません)。

これに対してShane Stanleyから「こうしたほうが」というツッコミがあったのが本Scriptです。HTMLファイルのファイルパスをNSDataに渡して読み込む、▲如璽燭NSAttaributedStringに読み込む という処理に変更。これまで読み込みに問題のあった(テキストエンコーディング判定失敗)HTMLも正しく読み込めているようです。

AppleScript名:HTMLをplain textに変換 v2
– Created 2017-09-09 by Takaaki Naganoya
– Created 2017-09-09 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
–http://piyocast.com/as/archives/4821

property NSAttributedString : a reference to current application’s NSAttributedString
property NSData : a reference to current application’s NSData

set aFile to choose file
set aPlainText to HTMLDecode(POSIX path of aFile) of me

on HTMLDecode(thePath)
  set theData to NSData’s dataWithContentsOfFile:thePath
  
set attStr to NSAttributedString’s alloc()’s initWithHTML:theData documentAttributes:(missing value)
  
return (attStr’s |string|()) as string
end HTMLDecode

★Click Here to Open This Script 

2017/09/08 HTMLをplain textに変換(UTF8)

HTMLのファイルをplain textに変換するAppleScriptです。

HTMLのplain text化とくに日本語テキスト入りのHTMLのPlain Text化は昔(Mac OS X 10.4ぐらいの時代)はひじょうに厄介な処理でした。それが、Cocoaの機能を使うと割と簡単にできるようになり、AppleScriptによる処理の「死角」が少なくなってきた印象があります。

HTMLのテキストエンコーディングについては、ヘッダーに書かれている文字コードと実際の文字コードが異なる可能性もあるため(ありがち)、いまのところテキストのエンコーディング自動判別ルーチンを併用しています。ただ、もうちょっと簡潔に処理できないかとも思うところです(2パスでHTMLを読み込んで、1パス目ではヘッダー部分のみ読み取ってエンコーディング情報を取得、2パス目で取得したエンコーディング情報に基づいて全体を読み直し、とか?)。

本ルーチンは、掲載のためにとりあえずHTMLがUTF-8で書かれているという前提にもとづいて処理を行なっています。

→ 改修版(v2)はこちら

AppleScript名:HTMLをplain textに変換(UTF8)
– Created 2017-09-08 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
–http://piyocast.com/as/archives/4818

property NSUnicodeStringEncoding : a reference to current application’s NSUnicodeStringEncoding
property NSAttributedString : a reference to current application’s NSAttributedString
property NSString : a reference to current application’s NSString

set aFile to choose file
set aRes to read aFile as «class utf8» –文字エンコーディング自動判定処理を行なったほうがよい
set aPlainText to HTMLDecode(aRes) of me

on HTMLDecode(HTMLString)
  set theString to NSString’s stringWithString:HTMLString
  
set theData to theString’s dataUsingEncoding:(NSUnicodeStringEncoding)
  
set attStr to NSAttributedString’s alloc()’s initWithHTML:theData documentAttributes:(missing value)
  
return (attStr’s |string|()) as string
end HTMLDecode

★Click Here to Open This Script 

2017/07/21 指定のPNG画像をASCII ART化してTextEditでオープン v2

jp2aを利用して指定のPNG画像を色付きHTML形式のアスキーアート化して出力し、HTMLをRTFに変換してTextEditでオープンしてフォントを変更するAppleScriptです。

指定のJPEG画像をアスキーアート化するjp2aは、Homebrew経由でインストールしてください。

asciiart4_resized.png

asciiart3_resized.png
▲このように縦長で余白の多い画像から、自動で余白部分をトリミングして処理

asciiart_z.png
▲左側はPNG画像の余白トリミング処理を行ったもの、右側はトリミング処理を行わなかったもの

アスキーアート化するにあたって、元画像の余白部分をトリミングできたほうが良好な結果が得られるため、処理対象をJPEG画像からPNG画像(背景透過)に変更し、以前に使った画像余白トリミングフレームワーク「KGPixelBoundsClipKit」を用いてトリミングしてJPEG画像に変換。

トリミングしたJPEG画像をjp2aでHTMLのアスキーアートに変換し、さらにHTMLをスタイル付きテキスト(NSAttributedString)に変換。

スタイル付きテキストをRTF(リッチテキストフォーマット)に変換してファイル出力。RTFになればTextEditで扱えるので、TextEditでオープンして本文のフォントを等幅フォント(Osaka-mono)に指定してウィンドウのサイズを変更しています。

テストする際には、KGPixelBoundsClipKitフレームワークのバイナリを~/Library/Frameworksフォルダに入れてお試しください。

–> Download Framework Binary

AppleScript名:指定のPNG画像をASCII ART化してTextEditでオープン v2
– Created 2017-07-21 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use framework “KGPixelBoundsClipKit” –https://github.com/kgn/KGPixelBoundsClip
–http://piyocast.com/as/archives/4736

set aFile to choose file of type {“public.png”}

–PNG画像の余白をトリミング
set anImage to (current application’s NSImage’s alloc()’s initWithContentsOfFile:(POSIX path of aFile))
set bImage to anImage’s imageClippedToPixelBounds()

–トリミング結果をデスクトップにJPEG形式で保存
set aDesktopPath to (current application’s NSProcessInfo’s processInfo()’s environment()’s objectForKey:(“HOME”))’s stringByAppendingString:“/Desktop/”
set savePath to aDesktopPath’s stringByAppendingString:((current application’s NSUUID’s UUID()’s UUIDString())’s stringByAppendingString:“.jpg”)
set fRes to saveNSImageAtPathAsJPG(bImage, savePath, 100) of me

–ASCII ARTに変換してHTMLとして出力
set anAlias to (POSIX file (savePath as string)) as alias
set htmlRes to jpegToAsciiArt(anAlias, 120) of me

–出力されたHTMLデータを評価してスタイル付きテキストに変換
set htmlData to current application’s NSString’s stringWithString:htmlRes
set keyList to {current application’s NSDocumentTypeDocumentAttribute, current application’s NSCharacterEncodingDocumentAttribute}
set valList to {current application’s NSHTMLTextDocumentType, current application’s NSUTF8StringEncoding}
set optDict to current application’s NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList
set aStyledStr to current application’s NSAttributedString’s alloc()’s initWithData:(htmlData’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)) options:optDict documentAttributes:(missing value) |error|:(missing value)

–スタイル付きテキストをRTFとしてデスクトップに保存
set targFol to POSIX path of (path to desktop)
set aUUID to current application’s NSUUID’s UUID()’s UUIDString() as text
set bRes to my saveStyledTextAsRTF(aUUID, targFol, aStyledStr) –PDFで書き出す
set newPath to targFol & aUUID & “.rtf”

–保存したRTFをTextEditでオープンして等幅フォント設定して、Window横幅を変更
tell application “TextEdit”
  activate
  
open (POSIX file newPath) as alias
  
  
tell text of document 1
    set font of every attribute run to “Osaka-Mono”
  end tell
  
  
tell window 1
    set {x1, y1, x2, y2} to bounds
    
set bounds to {x1, y1, (x1 + 800), y2}
  end tell
end tell

–NSImageを指定パスにJPEG形式で保存
on saveNSImageAtPathAsJPG(anImage, outPath, qulityNum as real)
  set imageRep to anImage’s TIFFRepresentation()
  
set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep
  
set pathString to current application’s NSString’s stringWithString:outPath
  
set newPath to pathString’s stringByExpandingTildeInPath()
  
set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSJPEGFileType) |properties|:{NSImageCompressionFactor:qulityNum})
  
set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean
  
return aRes –true/false
end saveNSImageAtPathAsJPG

–与えられたファイルパスのJPEG画像をASCII ARTに変換して返す
on jpegToAsciiArt(anImageAlias, digitNum as integer)
  set sText to “/usr/local/bin/jp2a -f –html-raw –colors –width=” & (digitNum as string) & ” -i “ & quoted form of POSIX path of anImageAlias
  
set tRes to do shell script sText
  
return tRes
end jpegToAsciiArt

–スタイル付きテキストを指定フォルダ(POSIX path)にRTFで書き出し
on saveStyledTextAsRTF(aFileName, targFol, aStyledString)
  –Convert NSMutableStyledStrings to RTF
  
set bstyledLength to aStyledString’s |string|()’s |length|()
  
set bDict to current application’s NSDictionary’s dictionaryWithObject:“NSRTFTextDocumentType” forKey:(current application’s NSDocumentTypeDocumentAttribute)
  
set bRTF to aStyledString’s RTFFromRange:(current application’s NSMakeRange(0, bstyledLength)) documentAttributes:bDict
  
  
– build path based on title
  
set theName to current application’s NSString’s stringWithString:aFileName
  
set theName to theName’s stringByReplacingOccurrencesOfString:“/” withString:“_”
  
set theName to theName’s stringByReplacingOccurrencesOfString:“:” withString:“_”
  
set thePath to current application’s NSString’s stringWithString:targFol
  
set thePath to (thePath’s stringByAppendingPathComponent:theName)’s stringByAppendingPathExtension:“rtf”
  
  
return (bRTF’s writeToFile:thePath atomically:true) as boolean
end saveStyledTextAsRTF

★Click Here to Open This Script 

2017/07/21 指定のJPEG画像をASCII ART(カラーhtml)化してクリップボードに転送

jp2aを利用して指定のJPEG画像を色付きHTML形式のアスキーアート化して出力し、HTMLをスタイル付きテキストに変換してクリップボードに入れるAppleScriptです。

指定のJPEG画像をアスキーアート化するjp2aは、Homebrew経由でインストールしてください。

Terminal.app上で、

  sudo brew install jp2a

でインストールできます。

HTML形式で出力したASCII ARTをスタイル付きテキストに変換するあたりにCocoaの機能(NSAttributedString)を用いています。

実行するとアスキーアート化する対象のJPEG画像を選択。クリップボードに書式付きテキストの状態で入るため、書式付きテキスト対応のエディタ(テキストエディットなど)にペーストしてください。

asciiart1_resized.png

asciiart2_resized.png

AppleScript名:指定のJPEG画像をASCII ART(カラーhtml)化してクリップボードに転送
– Created 2017-07-21 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
–http://piyocast.com/as/archives/4733

set aFile to choose file of type {“public.jpeg”}
set htmlRes to jpegToAsciiArt(aFile, 100) of me
set htmlData to current application’s NSString’s stringWithString:htmlRes

set keyList to {current application’s NSDocumentTypeDocumentAttribute, current application’s NSCharacterEncodingDocumentAttribute}
set valList to {current application’s NSHTMLTextDocumentType, current application’s NSUTF8StringEncoding}

set optDict to current application’s NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList

set aStyledStr to current application’s NSAttributedString’s alloc()’s initWithData:(htmlData’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)) options:optDict documentAttributes:(missing value) |error|:(missing value)

set attrList to {aStyledStr}
restoreClipboard(attrList) of me

–与えられたファイルパスのJPEG画像をASCII ARTに変換して返す
on jpegToAsciiArt(anImageAlias, digitNum as integer)
  set sText to “/usr/local/bin/jp2a -f –html-raw –colors –width=” & (digitNum as string) & ” -i “ & quoted form of POSIX path of anImageAlias
  
set tRes to do shell script sText
  
return tRes
end jpegToAsciiArt

–set the clipboard to….
on restoreClipboard(theArray as list)
  set thePasteboard to current application’s NSPasteboard’s generalPasteboard()
  
thePasteboard’s clearContents()
  
thePasteboard’s writeObjects:theArray
end restoreClipboard

★Click Here to Open This Script 

2017/05/26 書式つきテキストを組み立てて、クリップボードに設定

書式つきテキスト(NSAttributedString)を組み立てて、クリップボードに設定するAppleScriptです。

作成した書式つきテキストは、そのままKeynoteなどのアプリケーションにペーストして利用することが可能です。グラフィックではないため、アプリケーション上での再編集や影の指定、色の変更などが可能です。

styles.png

Keynoteでアウトライン文字を使いたいことはままあるので、このように手軽にクリップボードに転送して利用できると実用性が高いことでしょう。

後日談:という紹介をしたら、KeynoteのヘビーユーザーからKeynoteのGUI上からアウトライン文字の書式を指定できることを教えてもらいました。

AppleScript名:書式つきテキストを組み立てて、クリップボードに設定
– Created 2017-05-26 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
–http://piyocast.com/as/archives/4662

set anAssrStr to makeRTFfromParameters(“ぴよまるソフトウェア”, 3.0, 72) of me

set attrList to {anAssrStr}
restoreClipboard(attrList) of me –set the clipboard to rtf_data

–書式つきテキストを組み立てる
on makeRTFfromParameters(aStr as string, outlineNum as real, aFontSize as real)
  –フォント
  
set aVal1 to current application’s NSFont’s fontWithName:“HiraKakuStdN-W8″ |size|:aFontSize
  
set aKey1 to (current application’s NSFontAttributeName)
  
  
–色
  
set aVal2 to current application’s NSColor’s blueColor()
  
set aKey2 to (current application’s NSForegroundColorAttributeName)
  
  
–カーニング
  
set aVal3 to -2.0
  
set akey3 to (current application’s NSKernAttributeName)
  
  
–アンダーライン
  
set aVal4 to 0
  
set akey4 to (current application’s NSUnderlineStyleAttributeName)
  
  
–リガチャ
  
set aVal5 to 2 –全てのリガチャを有効にする
  
set akey5 to (current application’s NSLigatureAttributeName)
  
  
–枠線(アウトライン)
  
set aVal6 to outlineNum
  
set akey6 to (current application’s NSStrokeWidthAttributeName)
  
  
set keyList to {aKey1, aKey2, akey3, akey4, akey5, akey6}
  
set valList to {aVal1, aVal2, aVal3, aVal4, aVal5, aVal6}
  
set attrsDictionary to current application’s NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList
  
  
set attrStr to current application’s NSMutableAttributedString’s alloc()’s initWithString:aStr attributes:attrsDictionary
  
return attrStr
  
end makeRTFfromParameters

–From Shane Stanley’s Book “Everyday AppleScriptObjC”
on restoreClipboard(theArray as list)
  set thePasteboard to current application’s NSPasteboard’s generalPasteboard()
  
thePasteboard’s clearContents()
  
thePasteboard’s writeObjects:theArray
end restoreClipboard

★Click Here to Open This Script 

2017/03/27 実体参照している文字列をデコードする(ASOC)

HTMLの中などで実体参照(Character reference)しているエンコードされた文字列をデコードするAppleScriptのCocoa呼び出し版です(Pure AppleScript版はこちら)。

AppleScript名:実体参照している文字列をデコードする(ASOC)
– Created 2017-01-18 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
–http://piyocast.com/as/archives/4568

set aStr to "龍馬伝"
set aRes to decodeCharacterReference(aStr) of me
–>  "龍馬伝"

set aStr to "\"第2エア\""
set aRes to decodeCharacterReference(aStr) of me
–>  "\"第2エア\""

on decodeCharacterReference(aStr)
  set anNSString to current application’s NSString’s stringWithString:aStr
  
set theData to anNSString’s dataUsingEncoding:(current application’s NSUTF16StringEncoding)
  
set styledString to current application’s NSAttributedString’s alloc()’s initWithHTML:theData documentAttributes:(missing value)
  
set plainText to (styledString’s |string|()) as string
  
return plainText
end decodeCharacterReference

★Click Here to Open This Script 

2017/01/27 ASOCの美しい書き方?

AppleScriptからCocoaの機能を呼び出すことができるようになり、AppleScript本来の簡潔な記述はしにくくなりました。

ASOCの記述方法について、どのようなアプローチが可能かをまとめてみました。

(1)は、ふだん書いているやり方です。一番安全で確実にAppleScriptの処理系に解釈されるので、トラブル回避のためにこの書き方をしています。ただし、1行がものすごく長くなるので、本Blogに掲載したときの「見た目」がよろしくありません(エディタの上では問題ないのですが、、、)

(2)は、Xcode上のAppleScriptでよくやる書き方です。インデントを基本としたAppleScriptらしいスタイルにはなっているものの、書かなくてはならない情報が多く、やや面倒と感じます。

(3)は、(2)でインデントの段数の増えすぎたことに対する改良とでも呼ぶべきものでしょうか。「its」を毎回書く必要があることに対し、抵抗感があるかないかが問題でしょう。

(4)は、Script Debugger 6のテンプレートに入っていた記述で、なかなかいい手だと思います(Xcode上でもやっていましたが)。ただ、プログラムが長く複雑になると冒頭のProperty宣言部分がどんどん長くなるという問題もあります。

サンプルとして書くのであれば、(4)あたりを検討すべきなんでしょう。

AppleScript名:(1)quick style
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4412

set a to (current application’s NSString’s stringWithString:“aaaaa”) as string
–>  ”aaaaa”

★Click Here to Open This Script 

AppleScript名:(2)xcode style
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4412

tell current application
  tell class “NSString”
    set a to (its stringWithString:“aaaaa”) as string
  end tell
end tell
–>  ”aaaaa”

★Click Here to Open This Script 

AppleScript名:(3)layer style
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4412

tell current application’s NSString
  set a to (its stringWithString:“aaaa”) as string
end tell
–>  ”aaaa”

★Click Here to Open This Script 

AppleScript名:(4)mark alldritt style
use AppleScript version “2.4″
use framework “Foundation”
use scripting additions
–http://piyocast.com/as/archives/4412

property NSString : a reference to current application’s NSString

set a to (NSString’s stringWithString:“aaaa”) as string
–>  ”aaaa”

★Click Here to Open This Script 

実際に(4)のスタイルで書いてみたら、NSMakeRangeやNSMaxRangeなどのObjective-Cのメソッドでない部分を同じスタイルに統一できなくて(current application’sを省略できなくて)、化けきれていない感じが、、、、

あとは、スクリプトエディタ上だとほとんど構文要素の変化に乏しく、メリハリがない(構文要素カラーリングの効果がなく)ので書く方にとって読みにくくなるような気がします。

macOS標準搭載のスクリプトエディタでは、Cocoaのclass名もmethod名も同じ色で表示されてしまいますが、ASObjC Explorer 4やScript Debugger 6ではmethod名を別の色で表示する機能が実装されているため、やはりそうしたツールがないと辛い感じです。

mi.png

AppleScript名:テキストエディタ「mi」で選択中のテキストからHTMLタグを外して逆順に並べなおす
– Created 2017-01-27 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4412

property NSString : a reference to current application’s NSString
property NSAttributedString : a reference to current application’s NSAttributedString
property NSArray : a reference to current application’s NSArray
property NSMutableArray : a reference to current application’s NSMutableArray
property NSUTF16StringEncoding : a reference to current application’s NSUTF16StringEncoding

tell application “mi”
  tell document 1
    set aText to selection
  end tell
end tell

–選択部分のテキストからHTMLのタグを外す
set anNSString to NSString’s stringWithString:aText
set theData to anNSString’s dataUsingEncoding:(NSUTF16StringEncoding)
set styledString to NSAttributedString’s alloc()’s initWithHTML:theData documentAttributes:(missing value)
set plainText to (styledString’s |string|())

–テキストを行ごとにparseしてNSArrayに
set anArray to NSMutableArray’s alloc()’s init()
set aRange to current application’s NSMakeRange(0, plainText’s |length|())

repeat while aRange’s |length|() > 0
  set subRange to plainText’s lineRangeForRange:(current application’s NSMakeRange(aRange’s location(), 0))
  
  
–行が改行コードまで取得されるので、改行コードを除外するように微調整
  
copy subRange to tmpRange
  
set tmpRange’s |length| to ((subRange’s |length|()) - 1) –微調整
  
set aLine to plainText’s substringWithRange:tmpRange
  
anArray’s addObject:aLine
  
  
set aRange’s location to (current application’s NSMaxRange(subRange))
  
set aRange’s |length| to ((aRange’s |length|()) - (subRange’s |length|()))
end repeat

–NSArrayを逆順に(reverse order array)
set outArray to (anArray’s reverseObjectEnumerator())’s allObjects()

–NSArray to string with line delimiter
set outStr to retStrFromArrayWithDelimiter(outArray, return) of me

–リストを指定デリミタをはさんでテキスト化
on retStrFromArrayWithDelimiter(aList, aDelim)
  set anArray to NSArray’s arrayWithArray:aList
  
set aRes to anArray’s componentsJoinedByString:aDelim
  
return aRes as text
end retStrFromArrayWithDelimiter

★Click Here to Open This Script 

2017/01/03 Notesの指定エントリの本文をプレーンテキストとして取得

macOS標準搭載アプリ「メモ」(英語名:Notes)の指定エントリの本文をプレーンテキストとして取得するAppleScriptです。

メモの本文(body)がHTMLとして取得されるので、HTMLからスタイル付きテキスト(NSAttributedString)を経由してプレーンテキストに変換します。

AppleScript名:Notesの指定エントリの本文をプレーンテキストとして取得
– Created 2017-01-03 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

tell application “Notes”
  tell note 1 –とりあえず最新のエントリを指定
    set theBody to body
  end tell
end tell

set anNSString to current application’s NSString’s stringWithString:theBody
set theData to anNSString’s dataUsingEncoding:(current application’s NSUTF16StringEncoding)
set styledString to current application’s NSAttributedString’s alloc()’s initWithHTML:theData documentAttributes:(missing value)

set plainText to (styledString’s |string|()) as string

★Click Here to Open This Script 

2016/11/29 バンドル形式のAppleScript自身の「説明」を取得する v3

バンドル形式のAppleScript自身に書かれている「説明」の文章を取得するAppleScriptです。

path to meで自分自身のパスを取得したあと、ファイルタイプ(type identifier)を問い合わせるように変更しました。

AppleScript名:バンドル形式のAppleScript自身の「説明」(description.rtfd/TXT.rtf)を取得する v3
【コメント】 このScriptの説明文を書いておきますよー
– Created 2016-10-12 by Takaaki Naganoya
– Created 2016-11-28 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
–http://piyocast.com/as/archives/4268

set cRes to retMyComment() of me
–> "このScriptの説明文を書いておきますよー"

on retMyComment()
  set myPath to (path to me)
  
tell application "System Events"
    set myType to type identifier of myPath
  end tell
  
if myType is not equal to "com.apple.applescript.script-bundle" then return ""
  
  
set docPath to (myPath as string) & "Contents:Resources:description.rtfd:TXT.rtf"
  
set aRes to retTextFromRTF(docPath) of me
  
return aRes
end retMyComment

on retTextFromRTF(aFile)
  set aFilePath to current application’s NSString’s stringWithString:(POSIX path of aFile)
  
set aData to current application’s NSData’s dataWithContentsOfFile:aFilePath options:0 |error|:(missing value)
  
set theStyledText to current application’s NSMutableAttributedString’s alloc()’s initWithData:aData options:(missing value) documentAttributes:(missing value) |error|:(missing value)
  
  
if theStyledText is not equal to missing value then
    return (theStyledText’s |string|()) as string
  else
    return false –Not RTF file
  end if
end retTextFromRTF

★Click Here to Open This Script 

2015/09/22 クリップボードの内容をRTFとPDFとHTMLで書き出す

Cocoaの機能を用いて、クリップボードの内容をデスクトップにRTFとPDFで書き出すAppleScriptの改訂版です。

前バージョンのAppleScriptでは、スタイル付きテキスト(NSAttributedString)をHTMLに書き出すと、HTML内のタグでは「UTF-8」になっていながらも、HTMLのテキスト自体のエンコーディングがShift JISというたいへん不思議な状態になっていました。

スタイル付きテキスト(NSAttributedString)の取得部分に問題がないことを確認。スタイル付きテキストをPDFやRTFに書き出した場合には問題なし。HTMLの書き出しに固有の根の深い問題があるのかと疑っていましたが・・・難易度でいえば、それほど難しくない話でした。

修正部分はたった1箇所。最後にHTMLをファイルに書き込む際に、UTF-8(NSUTF8StringEncoding)を指定する記述を追加しただけです。

テキストエンコーディングの省略時にはかならず「UTF-8」が指定されるものとばかり思っていましたが、明示的に指定しないとダメということがよくわかりました。

AppleScript名:クリップボードの内容をRTFとPDFとHTMLで書き出す v2
– Created 2015-09-20 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit” – for NSPasteboard, which is the clipboard

–クリップボードの内容をNSAttributedStringに
set anAttr to my getClipboardASStyledText()

–保存先とファイル名を求める
set targFol to POSIX path of (path to desktop)
set aUUID to current application’s NSUUID’s UUID()’s UUIDString() as text

set aRes to my saveStyledTextAsRTF(aUUID, targFol, anAttr) –RTFで書き出す
set bRes to my saveStyledTextAsPDF(aUUID, targFol, anAttr) –PDFで書き出す
set cRes to my saveStyledTextAsHTML(aUUID, targFol, anAttr) –HTMLで書き出す

– クリップボードの内容をNSAttributedStringとして取り出して返す
on getClipboardASStyledText()
  set theNSPasteboard to current application’s NSPasteboard’s generalPasteboard()
  
set theAttributedStringNSArray to theNSPasteboard’s readObjectsForClasses:({current application’s NSAttributedString}) options:(missing value)
  
set theNSAttributedString to theAttributedStringNSArray’s objectAtIndex:0
  
return theNSAttributedString
end getClipboardASStyledText

–スタイル付きテキストを指定フォルダ(POSIX path)にRTFで書き出し
on saveStyledTextAsRTF(aFileName, targFol, aStyledString)
  –Convert NSMutableStyledStrings to RTF
  
set bstyledLength to aStyledString’s |string|()’s |length|()
  
set bDict to current application’s NSDictionary’s dictionaryWithObject:“NSRTFTextDocumentType” forKey:(current application’s NSDocumentTypeDocumentAttribute)
  
set bRTF to aStyledString’s RTFFromRange:(current application’s NSMakeRange(0, bstyledLength)) documentAttributes:bDict
  
  
– build path based on title
  
set theName to current application’s NSString’s stringWithString:aFileName
  
set theName to theName’s stringByReplacingOccurrencesOfString:“/” withString:“_”
  
set theName to theName’s stringByReplacingOccurrencesOfString:“:” withString:“_”
  
set thePath to current application’s NSString’s stringWithString:targFol
  
set thePath to (thePath’s stringByAppendingPathComponent:theName)’s stringByAppendingPathExtension:“rtf”
  
  
return (bRTF’s writeToFile:thePath atomically:true) as boolean
end saveStyledTextAsRTF

–スタイル付きテキストを指定フォルダ(POSIX path)にPDFで書き出し
on saveStyledTextAsPDF(aFileName, targFol, aStyledString)
  – get page size being used for printing
  
set printInfo to current application’s NSPrintInfo’s sharedPrintInfo()
  
set pageSize to printInfo’s paperSize()
  
set theLeft to printInfo’s leftMargin()
  
set theTop to printInfo’s topMargin()
  
  
– make a text view
  
set theView to current application’s NSTextView’s alloc()’s initWithFrame:{origin:{x:0, y:0}, |size|:pageSize}
  
theView’s setTextContainerInset:{theLeft, theTop}
  
  
– put in the text
  
theView’s textStorage()’s setAttributedString:aStyledString
  
set theData to theView’s dataWithPDFInsideRect:{origin:{x:0, y:0}, |size|:pageSize}
  
  
– build path based on title
  
set theName to current application’s NSString’s stringWithString:aFileName
  
set theName to theName’s stringByReplacingOccurrencesOfString:“/” withString:“_”
  
set theName to theName’s stringByReplacingOccurrencesOfString:“:” withString:“_”
  
set thePath to current application’s NSString’s stringWithString:targFol
  
set thePath to (thePath’s stringByAppendingPathComponent:theName)’s stringByAppendingPathExtension:“pdf”
  
  
return (theData’s writeToFile:thePath atomically:true) as boolean
end saveStyledTextAsPDF

–スタイル付きテキストを指定フォルダ(POSIX path)にHTMLで書き出し
on saveStyledTextAsHTML(aFileName, targFol, aStyledString)
  –Convert NSMutableStyledStrings toHTML
  
set theNSDictionary to current application’s NSMutableDictionary’s dictionaryWithObject:(current application’s NSHTMLTextDocumentType) forKey:(current application’s NSDocumentTypeDocumentAttribute)
  
set theNSData to aStyledString’s dataFromRange:{location:0, |length|:aStyledString’s |length|()} documentAttributes:theNSDictionary |error|:(missing value)
  
set aHTML to current application’s NSString’s alloc()’s initWithData:theNSData encoding:(current application’s NSUTF8StringEncoding)
  
  
– build path based on title
  
set theName to current application’s NSString’s stringWithString:aFileName
  
set theName to theName’s stringByReplacingOccurrencesOfString:“/” withString:“_”
  
set theName to theName’s stringByReplacingOccurrencesOfString:“:” withString:“_”
  
set thePath to current application’s NSString’s stringWithString:targFol
  
set thePath to (thePath’s stringByAppendingPathComponent:theName)’s stringByAppendingPathExtension:“html”
  
  
return (aHTML’s writeToFile:thePath atomically:true encoding:(current application’s NSUTF8StringEncoding) |error|:(missing value)) as boolean
  
end saveStyledTextAsHTML

★Click Here to Open This Script 

2015/09/20 クリップボードの内容をRTFとPDFで書き出す

Cocoaの機能を用いて、クリップボードの内容をデスクトップにRTFとPDFで書き出すAppleScriptです。

HTMLでも書き出せるのですが、日本語の文字化け(UTF-8で書き出したつもりがShift JISになっていた問題)が解決されていないため、とりあえずこんなもんで。

AppleScript名:クリップボードの内容をRTFとPDFで書き出す
– Created 2015-09-20 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit” – for NSPasteboard, which is the clipboard

–クリップボードの内容をNSAttributedStringに
set anAttr to my getClipboardASStyledText()

–保存先とファイル名を求める
set targFol to POSIX path of (path to desktop)
set aUUID to current application’s NSUUID’s UUID()’s UUIDString() as text

set aRes to my saveStyledTextAsRTF(aUUID, targFol, anAttr) –RTFで書き出す
set bRes to my saveStyledTextAsPDF(aUUID, targFol, anAttr) –PDFで書き出す

– クリップボードの内容をNSAttributedStringとして取り出して返す
on getClipboardASStyledText()
  set theNSPasteboard to current application’s NSPasteboard’s generalPasteboard()
  
set theAttributedStringNSArray to theNSPasteboard’s readObjectsForClasses:({current application’s NSAttributedString}) options:(missing value)
  
set theNSAttributedString to theAttributedStringNSArray’s objectAtIndex:0
  
return theNSAttributedString
end getClipboardASStyledText

–スタイル付きテキストを指定フォルダ(POSIX path)にRTFで書き出し
on saveStyledTextAsRTF(aFileName, targFol, aStyledString)
  –Convert NSMutableStyledStrings to RTF
  
set bstyledLength to aStyledString’s |string|()’s |length|()
  
set bDict to current application’s NSDictionary’s dictionaryWithObject:“NSRTFTextDocumentType” forKey:(current application’s NSDocumentTypeDocumentAttribute)
  
set bRTF to aStyledString’s RTFFromRange:(current application’s NSMakeRange(0, bstyledLength)) documentAttributes:bDict
  
  – build path based on title
  
set theName to current application’s NSString’s stringWithString:aFileName
  
set theName to theName’s stringByReplacingOccurrencesOfString:“/” withString:“_”
  
set theName to theName’s stringByReplacingOccurrencesOfString:“:” withString:“_”
  
set thePath to current application’s NSString’s stringWithString:targFol
  
set thePath to (thePath’s stringByAppendingPathComponent:theName)’s stringByAppendingPathExtension:“rtf”
  
  return (bRTF’s writeToFile:thePath atomically:true) as boolean
end saveStyledTextAsRTF

–スタイル付きテキストを指定フォルダ(POSIX path)にPDFで書き出し
on saveStyledTextAsPDF(aFileName, targFol, aStyledString)
  – get page size being used for printing
  
set printInfo to current application’s NSPrintInfo’s sharedPrintInfo()
  
set pageSize to printInfo’s paperSize()
  
set theLeft to printInfo’s leftMargin()
  
set theTop to printInfo’s topMargin()
  
  – make a text view
  
set theView to current application’s NSTextView’s alloc()’s initWithFrame:{origin:{x:0, y:0}, |size|:pageSize}
  
theView’s setTextContainerInset:{theLeft, theTop}
  
  – put in the text
  
theView’s textStorage()’s setAttributedString:aStyledString
  
set theData to theView’s dataWithPDFInsideRect:{origin:{x:0, y:0}, |size|:pageSize}
  
  – build path based on title
  
set theName to current application’s NSString’s stringWithString:aFileName
  
set theName to theName’s stringByReplacingOccurrencesOfString:“/” withString:“_”
  
set theName to theName’s stringByReplacingOccurrencesOfString:“:” withString:“_”
  
set thePath to current application’s NSString’s stringWithString:targFol
  
set thePath to (thePath’s stringByAppendingPathComponent:theName)’s stringByAppendingPathExtension:“pdf”
  
  return (theData’s writeToFile:thePath atomically:true) as boolean
end saveStyledTextAsPDF

★Click Here to Open This Script 

2015/09/19 Notes上の指定のエントリをHTMLとして書き出す

Cocoaの機能を使って、Notes(日本語名:「メモ」)の指定エントリの内容をHTMLとして書き出すAppleScriptです。

ただ、普通にPDFやRTFと同様に出力してみたら・・・文字化けしてしまいました(汗)。

html1.png

UTF-8で出力しているはずなのですが、

html2.png

Safariで文字エンコーディングを「日本語(Shift JIS)」に設定すると・・・

html3.png

html4.png

文字化けしなくなります。

html5.png

保存されたHTMLのソースを見ると、エンコーディングはUTF-8となっているのですが、ソースをUTF-8でオープンしても文字化けしたままです。

AppleScript名:Notes上の指定のエントリをHTMLとして書き出す
– Created 2015-09-18 by Shane Stanley
– Modified 2015-09-19 by Takaaki Naganoya
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

set targFol to POSIX path of (path to desktop)

tell application "Notes"
  set theBody to body of note 2
  
set theName to name of note 2 – for file name
end tell

– Notesの本文をスタイル付きテキストに
set anNSString to current application’s NSString’s stringWithString:theBody
set theData to anNSString’s dataUsingEncoding:(current application’s NSUTF16StringEncoding)
set styledString to current application’s NSAttributedString’s alloc()’s initWithHTML:theData documentAttributes:(missing value)

set cRes to my saveStyledTextAsHTML(theName, targFol, styledString)
–> true

–スタイル付きテキストを指定フォルダ(POSIX path)にHTMLで書き出し
on saveStyledTextAsHTML(aFileName, targFol, aStyledString)
  –Convert NSMutableStyledStrings toHTML
  
set theNSDictionary to current application’s NSMutableDictionary’s dictionaryWithObject:(current application’s NSHTMLTextDocumentType) forKey:(current application’s NSDocumentTypeDocumentAttribute)
  
set theNSData to aStyledString’s dataFromRange:{location:0, |length|:aStyledString’s |length|()} documentAttributes:theNSDictionary |error|:(missing value)
  
  
set aHTML to current application’s NSString’s alloc()’s initWithData:theNSData encoding:(current application’s NSUTF8StringEncoding)
  
  
– build path based on title
  
set theName to current application’s NSString’s stringWithString:aFileName
  
set theName to theName’s stringByReplacingOccurrencesOfString:"/" withString:"_"
  
set theName to theName’s stringByReplacingOccurrencesOfString:":" withString:"_"
  
set thePath to current application’s NSString’s stringWithString:targFol
  
set thePath to (thePath’s stringByAppendingPathComponent:theName)’s stringByAppendingPathExtension:"html"
  
  
return (aHTML’s writeToFile:thePath atomically:true) as boolean
  
end saveStyledTextAsHTML

★Click Here to Open This Script 

一応、Notes(メモ)から取得した本文データがHTMLだったので、Styled Textに変換しないでそのまま保存するバージョンも作ってみました。こちらであれば、文字化けは見られませんが・・・Styled Text(NSAttributedString)をHTMLに変換してファイル出力するという機能は、普通に文字化けせずに使えてほしいので、回避策を検討しておきたいところです。

AppleScript名:Notes上の指定のエントリをHTMLとして書き出す v2
– Created 2015-09-18 by Shane Stanley
– Modified 2015-09-19 by Takaaki Naganoya
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

set targFol to POSIX path of (path to desktop)

tell application "Notes"
  set theBody to body of note 2
  
set theName to name of note 2 – for file name
end tell

– Notesの本文をスタイル付きテキストに
set anNSString to current application’s NSString’s stringWithString:theBody
–>  (NSString) "<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">ASOCでできないこと<div><br></div><div>CFString の文字列(Cの文字列)を扱えない</div><div><br></div><div>block構文を必要とするAPIを呼べない</div><div><br></div><div>Key Value Observation を使えない(Xcode上ではOK?)</div></body></html>"

set aRes to my saveStyledTextAsHTML(theName, targFol, anNSString)

–スタイル付きテキストを指定フォルダ(POSIX path)にRTFで書き出し
on saveStyledTextAsHTML(aFileName, targFol, anNSString)
  
  
– build path based on title
  
set theName to current application’s NSString’s stringWithString:aFileName
  
set theName to theName’s stringByReplacingOccurrencesOfString:"/" withString:"_"
  
set theName to theName’s stringByReplacingOccurrencesOfString:":" withString:"_"
  
set thePath to current application’s NSString’s stringWithString:targFol
  
set thePath to (thePath’s stringByAppendingPathComponent:theName)’s stringByAppendingPathExtension:"html"
  
  
return (anNSString’s writeToFile:thePath atomically:true) as boolean
  
end saveStyledTextAsHTML

★Click Here to Open This Script 

2015/09/18 Notes上の指定のエントリをPDFやRTFとして書き出す

Cocoaの機能を使って、Notes(日本語名:「メモ」)の指定エントリの内容をPDFやRTFとして書き出すAppleScriptです。

  「・・・そんなもん作ってどうするんだ、本当に必要なのか?」

と、私自身が感じた内容ではありましたが、Shaneが質問に答えてMLに投稿し、それを私が日本語環境で検証して「文字化けするよー」とメールで報告してやりとりして、「ああ、Encodingがちがうんだー」ということでめでたく動くようになりました(NotesがデータをUTF-8ではなくUTF-16で保持していたのが原因ですが・・・El Capitanの新形式=iOS9上の新形式 だとどーなんだろう???)。

動くようになってはみたものの、あまりに特定の目的に最適化されたScriptだったので、データ取得部分と保存部分を別々に分け、スタイル付きテキストをPDFやRTFとして保存できるルーチンに整備して汎用性を確保しておきました。こういうのを作っておくと、あとになって地道に効いてくるはずです。たぶん・・・きっと。

実行すると、お手元の環境の「メモ」アプリの最新から2つ目のエントリの名称をファイル名にして、本文内容をデスクトップにPDFとRTFで保存します。

notes_entry.png

filenames.png

pdf.png

rtf.png

AppleScript名:Notes上の指定のエントリをPDFやRTFとして書き出す
– Created 2015-09-18 by Shane Stanley
– Modified 2015-09-18 by Takaaki Naganoya
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

set targFol to POSIX path of (path to desktop)

tell application “Notes”
  set theBody to body of note 2
  
set theName to name of note 2 – for file name
end tell

– Notesの本文をスタイル付きテキストに
set anNSString to current application’s NSString’s stringWithString:theBody
set theData to anNSString’s dataUsingEncoding:(current application’s NSUTF16StringEncoding) –日本語の環境&内容で検証ずみ。Chineseとかはどうか?
set styledString to current application’s NSAttributedString’s alloc()’s initWithHTML:theData documentAttributes:(missing value)

set aRes to my saveStyledTextAsPDF(theName, targFol, styledString)
–> true

set bRes to my saveStyledTextAsRTF(theName, targFol, styledString)
–> true

–スタイル付きテキストを指定フォルダ(POSIX path)にRTFで書き出し
on saveStyledTextAsRTF(aFileName, targFol, aStyledString)
  –Convert NSMutableStyledStrings to RTF
  
set bstyledLength to aStyledString’s |string|()’s |length|()
  
set bDict to current application’s NSDictionary’s dictionaryWithObject:“NSRTFTextDocumentType” forKey:(current application’s NSDocumentTypeDocumentAttribute)
  
set bRTF to aStyledString’s RTFFromRange:(current application’s NSMakeRange(0, bstyledLength)) documentAttributes:bDict
  
  
– build path based on title
  
set theName to current application’s NSString’s stringWithString:aFileName
  
set theName to theName’s stringByReplacingOccurrencesOfString:“/” withString:“_”
  
set theName to theName’s stringByReplacingOccurrencesOfString:“:” withString:“_”
  
set thePath to current application’s NSString’s stringWithString:targFol
  
set thePath to (thePath’s stringByAppendingPathComponent:theName)’s stringByAppendingPathExtension:“rtf”
  
  
return (bRTF’s writeToFile:thePath atomically:true) as boolean
end saveStyledTextAsRTF

–スタイル付きテキストを指定フォルダ(POSIX path)にPDFで書き出し
on saveStyledTextAsPDF(aFileName, targFol, aStyledString)
  – get page size being used for printing
  
set printInfo to current application’s NSPrintInfo’s sharedPrintInfo()
  
set pageSize to printInfo’s paperSize()
  
set theLeft to printInfo’s leftMargin()
  
set theTop to printInfo’s topMargin()
  
  
– make a text view
  
set theView to current application’s NSTextView’s alloc()’s initWithFrame:{origin:{x:0, y:0}, |size|:pageSize}
  
theView’s setTextContainerInset:{theLeft, theTop}
  
  
– put in the text
  
theView’s textStorage()’s setAttributedString:aStyledString
  
set theData to theView’s dataWithPDFInsideRect:{origin:{x:0, y:0}, |size|:pageSize}
  
  
– build path based on title
  
set theName to current application’s NSString’s stringWithString:aFileName
  
set theName to theName’s stringByReplacingOccurrencesOfString:“/” withString:“_”
  
set theName to theName’s stringByReplacingOccurrencesOfString:“:” withString:“_”
  
set thePath to current application’s NSString’s stringWithString:targFol
  
set thePath to (thePath’s stringByAppendingPathComponent:theName)’s stringByAppendingPathExtension:“pdf”
  
  
return (theData’s writeToFile:thePath atomically:true) as boolean
end saveStyledTextAsPDF

★Click Here to Open This Script