Archive for the 'NSMakeRange' Category

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

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

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

asciiart_gc1_resized.png

画像種別をとくに問わないように対応してみました。ただし、PNG画像については背景が透過している場合には画像余白トリミングフレームワーク「KGPixelBoundsClipKit」を用いてトリミングし、JPEG画像に変換します。

最大の変更点は、TextEditに対して命令を投げてフォントを指定していたものから、NSMutableAttributedStringに対してCocoaの機能を利用してフォント種別を指定するように変更したところです(意外と翻訳元となるObjective-Cの記述例が見つからない)。

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

–> Download Framework Binary

AppleScript名:指定の画像をASCII ART化してTextEditでオープン v3
– Created 2017-07-23 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/4740

set targFontName to “Osaka-Mono” –”Courier New”

set aFile to choose file of type {“public.image”}
tell application “System Events”
  set aType to type identifier of aFile –get UTI
end tell

if aType is equal to “public.png” then
  –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
  
set aaFile to (POSIX file (savePath as string)) as alias
  
else if aType is equal to “public.jpeg” then
  –JPEGの場合
  
copy aFile to aaFile
  
else
  –PNGとJPEG以外の場合には読み込んでJPEGに変換
  
set aImage to current application’s NSImage’s alloc()’s initWithContentsOfFile:(POSIX path of aFile)
  
set fRes to retUUIDfilePath(POSIX path of aFile, “jpg”) of me
  
set sRes to saveNSImageAtPathAsJPG(aImage, fRes, 100) of me
  
set aaFile to (POSIX file (fRes as string)) as alias
  
end if

–ASCII ARTに変換してHTMLとして出力
set htmlRes to jpegToAsciiArt(aaFile, 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 NSMutableAttributedString’s alloc()’s initWithData:(htmlData’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)) options:optDict documentAttributes:(missing value) |error|:(missing value)

–フォント種別およびサイズを指定してみた
set aRange to current application’s NSMakeRange(0, aStyledStr’s |length|())
set aVal1 to current application’s NSFont’s fontWithName:targFontName |size|:11
aStyledStr’s beginEditing()
aStyledStr’s addAttribute:(current application’s NSFontAttributeName) value:aVal1 range:aRange
aStyledStr’s endEditing()

–スタイル付きテキストを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”

–Macの画面(メインスクリーン)の高さを取得する
set dRec to ((current application’s NSScreen’s mainScreen())’s deviceDescription()’s NSDeviceSize) as record
set dHeight to (height of dRec) as integer

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

–指定ファイルパスと同一階層にファイル名をUUID、拡張子を指定したものを作成して返す
on retUUIDfilePath(aPath, aEXT)
  set aUUIDstr to (current application’s NSUUID’s UUID()’s UUIDString()) as string
  
set aPath to ((current application’s NSString’s stringWithString:aPath)’s stringByDeletingLastPathComponent()’s stringByAppendingPathComponent:aUUIDstr)’s stringByAppendingPathExtension:aEXT
  
return aPath
end retUUIDfilePath

–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)
  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
  
  
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 指定の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 

2015/12/04 AlphabetとNumericの混在かどうかを調べる

Cocoaの機能を用いて、アルファベットと数字の混在状態になっているかどうかを調べるAppleScriptです。

AppleScript名:AlphabetとNumericの混在かどうかを調べる
– Created 2015-12-04 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aRes to chkMixtureOfNumericAndAlphabet(“ABC”) of me
–>  false

set aRes to chkMixtureOfNumericAndAlphabet(“123″) of me
–>  false

set aRes to chkMixtureOfNumericAndAlphabet(“4f73vg1v”) of me –Target
–>  true

set aRes to chkMixtureOfNumericAndAlphabet(“4f73vg1vあああ”) of me
–>  false

–数字とアルファベットの混在状態の時にtrueを返す
on chkMixtureOfNumericAndAlphabet(checkString)
  set a0Res to chkAlphabetAndNumeric(checkString) of me
  
set a1Res to chkNumeric(checkString) of me
  
set a2Res to chkAlphabet(checkString) of me
  
  
if {a0Res, a1Res, a2Res} = {true, false, false} then
    return true
  else
    return false
  end if
  
end chkMixtureOfNumericAndAlphabet

–数字のみかを調べて返す
on chkNumeric(checkString)
  set digitCharSet to current application’s NSCharacterSet’s characterSetWithCharactersInString:“0123456789″
  
set ret to my chkCompareString:checkString baseString:digitCharSet
  
return ret as boolean
end chkNumeric

– アルファベットのみか調べて返す
on chkAlphabet(checkString)
  set aStr to current application’s NSString’s stringWithString:checkString
  
set allCharSet to current application’s NSMutableCharacterSet’s alloc()’s init()
  
allCharSet’s addCharactersInRange:(current application’s NSMakeRange(ASCII number of “a”, 26))
  
allCharSet’s addCharactersInRange:(current application’s NSMakeRange(ASCII number of “A”, 26))
  
set aBool to my chkCompareString:aStr baseString:allCharSet
  
return aBool as boolean
end chkAlphabet

– アルファベットと数字のみか調べて返す
on chkAlphabetAndNumeric(checkString)
  set aStr to current application’s NSString’s stringWithString:checkString
  
set allCharSet to current application’s NSMutableCharacterSet’s alloc()’s init()
  
allCharSet’s addCharactersInRange:(current application’s NSMakeRange(ASCII number of “0″, 10))
  
allCharSet’s addCharactersInRange:(current application’s NSMakeRange(ASCII number of “a”, 26))
  
allCharSet’s addCharactersInRange:(current application’s NSMakeRange(ASCII number of “A”, 26))
  
set aBool to my chkCompareString:aStr baseString:allCharSet
  
return aBool as boolean
end chkAlphabetAndNumeric

on chkCompareString:checkString baseString:baseString
  set aScanner to current application’s NSScanner’s localizedScannerWithString:checkString
  
aScanner’s setCharactersToBeSkipped:(missing value)
  
aScanner’s scanCharactersFromSet:baseString intoString:(missing value)
  
return (aScanner’s isAtEnd()) as boolean
end chkCompareString:baseString:

★Click Here to Open This Script 

2015/09/30 Unicodeの文字をNormalizeする

Cocoaの機能を用いて、NSStringの文字列をNormalizeするAppleScriptです。

たまたま仕事で、PDFの内容(テキスト)をparseしてデータを取り出して文字コードの範囲チェックをしていたところ・・・特定の文字のコード判定が思ったようにできず・・・調べてみたら、濁点つきのひらがな&カタカナがひっかかっていることが判明。これはNormalizeしてから処理するしかないだろーと考え、やり方を一通り調べてみました。

処理した結果がどうなっているかを調べるために、hexdumpのルーチンをつけています。

Normalizeしてからコード判定してみたら、問題なくできました。

AppleScript名:Unicodeの文字をNormalizeする
– Created 2015-09-30 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

–Reference:
–http://akisute.com/2010/05/utf-8-normalize.html
–http://nomenclator.la.coocan.jp/unicode/normalization.htm

set a to “がぎぐげご”
set aStr to current application’s NSString’s stringWithString:a
log hexDumpString(aStr)
–> {”E3″, “81″, “8C”, “E3″, “81″, “8E”, “E3″, “81″, “90″, “E3″, “81″, “92″, “E3″, “81″, “94″}

–NFD
set aNFD to aStr’s decomposedStringWithCanonicalMapping()
–>  (NSString) “がぎぐげご”
log hexDumpString(aNFD)
–> {”E3″, “81″, “8B”, “E3″, “82″, “99″, “E3″, “81″, “8D”, “E3″, “82″, “99″, “E3″, “81″, “8F”, “E3″, “82″, “99″, “E3″, “81″, “91″, “E3″, “82″, “99″, “E3″, “81″, “93″, “E3″, “82″, “99″}

–NFKD
set aNFKD to aStr’s decomposedStringWithCompatibilityMapping()
–>  (NSString) “がぎぐげご”
log hexDumpString(aNFKD)
–> {”E3″, “81″, “8B”, “E3″, “82″, “99″, “E3″, “81″, “8D”, “E3″, “82″, “99″, “E3″, “81″, “8F”, “E3″, “82″, “99″, “E3″, “81″, “91″, “E3″, “82″, “99″, “E3″, “81″, “93″, “E3″, “82″, “99″}

–NFC
set aNFC to aStr’s precomposedStringWithCanonicalMapping()
–>  (NSString) “がぎぐげご”
log hexDumpString(aNFC)
–> {”E3″, “81″, “8C”, “E3″, “81″, “8E”, “E3″, “81″, “90″, “E3″, “81″, “92″, “E3″, “81″, “94″}

–NFKC
set aNFKC to aStr’s precomposedStringWithCompatibilityMapping()
–>  (NSString) “がぎぐげご”
log hexDumpString(aNFKC)
–> {”E3″, “81″, “8C”, “E3″, “81″, “8E”, “E3″, “81″, “90″, “E3″, “81″, “92″, “E3″, “81″, “94″}

–NSStringをhexdumpする
on hexDumpString(theNSString)
  set theNSData to theNSString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set theString to (theNSData’s |description|()’s uppercaseString())
  
  
–Remove “< " ">” characters in head and tail
  
set tLength to (theString’s |length|()) - 2
  
set aRange to current application’s NSMakeRange(1, tLength)
  
set theString2 to theString’s substringWithRange:aRange
  
  
–Replace Space Characters
  
set aString to current application’s NSString’s stringWithString:theString2
  
set bString to aString’s stringByReplacingOccurrencesOfString:” “ withString:“”
  
  
set aResList to splitString(bString, 2)
  
–> {”E3″, “81″, “82″, “E3″, “81″, “84″, “E3″, “81″, “86″, “E3″, “81″, “88″, “E3″, “81″, “8A”}
  
  
return aResList
  
end hexDumpString

–Split NSString in specified aNum characters
on splitString(aText, aNum)
  
  
set aStr to current application’s NSString’s stringWithString:aText
  
if aStr’s |length|() aNum then return aText
  
  
set anArray to current application’s NSMutableArray’s new()
  
set mStr to current application’s NSMutableString’s stringWithString:aStr
  
  
set aRange to current application’s NSMakeRange(0, aNum)
  
  
repeat while (mStr’s |length|()) > 0
    if (mStr’s |length|()) < aNum then
      anArray’s addObject:(current application’s NSString’s stringWithString:mStr)
      
mStr’s deleteCharactersInRange:(current application’s NSMakeRange(0, mStr’s |length|()))
    else
      anArray’s addObject:(mStr’s substringWithRange:aRange)
      
mStr’s deleteCharactersInRange:aRange
    end if
  end repeat
  
  
return (current application’s NSArray’s arrayWithArray:anArray) as list
  
end splitString

★Click Here to Open This Script 

AppleScript名:Unicodeの文字を各方法でNormalizeして文字数をカウント
– Created 2015-10-02 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

–Reference:
–http://akisute.com/2010/05/utf-8-normalize.html
–http://nomenclator.la.coocan.jp/unicode/normalization.htm

set aRes to normalizeStrAndRetEachLength("がぎぐげご")
–> {origLen:5, NFD:10, NFKD:10, NFC:5, NFKC:5}
set bRes to normalizeStrAndRetEachLength("ぱぴぷぺぽ")
–> {origLen:5, NFD:10, NFKD:10, NFC:5, NFKC:5}
set cRes to normalizeStrAndRetEachLength("㌀")
–> {origLen:1, NFD:1, NFKD:5, NFC:1, NFKC:4}
set dRes to normalizeStrAndRetEachLength("㍿")
–> {origLen:1, NFD:1, NFKD:4, NFC:1, NFKC:4}
set eRes to normalizeStrAndRetEachLength("Å")
–> {origLen:1, NFD:2, NFKD:2, NFC:1, NFKC:1}
set fRes to normalizeStrAndRetEachLength("…")
–> {origLen:1, NFD:1, NFKD:3, NFC:1, NFKC:3}
set gRes to normalizeStrAndRetEachLength("")
–> {origLen:1, NFD:1, NFKD:3, NFC:1, NFKC:3}
set hRes to normalizeStrAndRetEachLength("")
–> {origLen:1, NFD:1, NFKD:2, NFC:1, NFKC:2}
set iRes to normalizeStrAndRetEachLength("")
–> {origLen:1, NFD:1, NFKD:3, NFC:1, NFKC:3}

on normalizeStrAndRetEachLength(a)
  set aStr to current application’s NSString’s stringWithString:a
  
set origLenNum to aStr’s |length|()
  
set aNFD to aStr’s decomposedStringWithCanonicalMapping()’s |length|() –NFD
  
set aNFKD to aStr’s decomposedStringWithCompatibilityMapping()’s |length|() –NFKD
  
set aNFC to aStr’s precomposedStringWithCanonicalMapping()’s |length|() –NFC
  
set aNFKC to aStr’s precomposedStringWithCompatibilityMapping()’s |length|() –NFKC
  
return {origLen:origLenNum, NFD:aNFD, NFKD:aNFKD, NFC:aNFC, NFKC:aNFKC}
end normalizeStrAndRetEachLength

★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/13 文字種別を判定する

Cocoaの機能を用いて文字種別の判定を行うAppleScriptです。

Objective-Cのものをそのまま書き換えたレベルですが、Pure AppleScriptでやるやり方(そもそも仕組みがないから、自分で文字コードを調べてひたすらループして判定)とはずいぶん違うことがわかります。

AppleScript名:ASOCで文字種別を判定する
– Created 2015-09-12 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

–http://core-tech.jp/gijutsublog/2014/06/23/10505

set aRes to my chkAlphabet:"p"
–>  true
set bRes to my chkAlphabet:"あ"
–>  false
set cRes to my chkMultiByteChar:"a"
–>  true
set dRes to my chkMultiByteChar:"ぴ"
–>  false
set eRes to my chkAlphaNumeric:"01A"
–>  true
set fRes to my chkAlphaNumeric:"%"
–>  false
set gRes to my chkAlphaNumericSymbol:"AAA`*+}{"
–>  true
set hRes to my chkNumeric:"0123"
–> true
set hRes to my chkNumeric:"0123A"
–> false

– アルファベットのみか
on chkAlphabet:checkString
  set aStr to current application’s NSString’s stringWithString:checkString
  
set allCharSet to current application’s NSMutableCharacterSet’s alloc()’s init()
  
allCharSet’s addCharactersInRange:(current application’s NSMakeRange(ASCII number of "a", 26))
  
allCharSet’s addCharactersInRange:(current application’s NSMakeRange(ASCII number of "A", 26))
  
set aBool to my chkCompareString:aStr baseString:allCharSet
  
return aBool as boolean
end chkAlphabet:

–数字のみか
on chkNumeric:checkString
  set digitCharSet to current application’s NSCharacterSet’s characterSetWithCharactersInString:"0123456789"
  
set ret to my chkCompareString:checkString baseString:digitCharSet
  
return ret as boolean
end chkNumeric:

–アルファベットと数字のみか
on chkAlphaNumeric:checkString
  set alnumCharSet to current application’s NSCharacterSet’s alphanumericCharacterSet()
  
set ret to my chkCompareString:checkString baseString:alnumCharSet
  
return ret as boolean
end chkAlphaNumeric:

–アルファベットと数字と記号のみか
on chkAlphaNumericSymbol:checkString
  set muCharSet to current application’s NSCharacterSet’s alphanumericCharacterSet()’s mutableCopy()
  
muCharSet’s addCharactersInString:"$\"!~&=#[]._-+`|{}?%^*/’@-/:;(),"
  
set ret to my chkCompareString:checkString baseString:muCharSet
  
return ret as boolean
end chkAlphaNumericSymbol:

–全角文字が存在するか
on chkMultiByteChar:checkString
  set aStr to current application’s NSString’s stringWithString:checkString
  
set aRes to aStr’s canBeConvertedToEncoding:(current application’s NSASCIIStringEncoding)
  
return (aRes as boolean)
end chkMultiByteChar:

on chkCompareString:checkString baseString:baseString
  set aScanner to current application’s NSScanner’s localizedScannerWithString:checkString
  
aScanner’s setCharactersToBeSkipped:(missing value)
  
aScanner’s scanCharactersFromSet:baseString intoString:(missing value)
  
return (aScanner’s isAtEnd()) as boolean
end chkCompareString:baseString:

★Click Here to Open This Script 

2015/09/02 ASOCで文字を逆順に

Cocoaの機能を用いて、テキストを逆順に(”Apple”→”elppA”)するAppleScriptです。

Pure AppleScriptで書くと2〜4行ぐらいの内容で、Pure AppleScriptで実行した方が高速です。

追記:Shane Stanleyから「そのままだと日本語のキャラクターとかに対応できないよ」という指摘があり、Shaneによる修正版(v2)を掲載。日本語ネイティブスピーカーとして申し訳ないです(汗)。

reverse_resized.png

Cocoaの機能を使う判断基準の参考にしたかったので、uuidを生成して連結したテキストを処理させてみると、

10回連結:ASOC版→0.061秒、Pure AS版:0.063秒

と、わずかにASOC版が高速という結果が出て、さらに1万回連結した巨大なテキストを処理させてみると、ASOC版がPure AppleScript版の2〜3倍ぐらいのスピードで処理できました(文字列連結・・・つまり、テスト用データの作成部分で差が出ているような気もしないではない)。

ほかに、ひらがなとカタカナの区別をちゃんとしたいとか、「函廚函屮螢奪肇襦廚同一視されるのは嫌だといった場合にはCocoaの機能を呼び出すことになるでしょう。

AppleScript名:ASOCで文字を逆順に v2
– Created 2015-09-01 by Takaaki Naganoya
– Modified 2015-09-01 by Shane Stanley –Consider CJK Characters & Emoji
–http://stackoverflow.com/questions/6720191/reverse-nsstring-text
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aUUID to (current application’s NSUUID’s UUID()’s UUIDString()) as text
–>  ”46EF17B7-CB3E-4DD9-BA8A-013D3B30A80A”

set aUUID to 😀😐 & aUUID & 😀😐
–>  ”😀😐46EF17B7-CB3E-4DD9-BA8A-013D3B30A80A😀😐

set revUUID to reversedStr(aUUID) as text
–>  ”😐😀A08A03B3D310-A8AB-9DD4-E3BC-7B71FE64😐😀

on reversedStr(paramStr as text)
  set aStr to current application’s NSString’s stringWithString:paramStr
  
set strLength to aStr’s |length|()
  
set revStr to current application’s NSMutableString’s stringWithCapacity:strLength
  
set charIndex to strLength - 1
  
repeat while charIndex > -1
    set subStrRange to aStr’s rangeOfComposedCharacterSequenceAtIndex:charIndex
    
revStr’s appendString:(aStr’s substringWithRange:subStrRange)
    
set charIndex to (location of subStrRange) - 1
  end repeat
  
  
return revStr
end reversedStr

★Click Here to Open This Script 

日本語文字列の入ったNSString/NSMutableStringから1文字取り出す処理の追試を行っておきました。なるほど。

AppleScript名:ASOCで文字列から一部分を取り出す
– Created 2015-09-02 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aStr to current application’s NSString’s stringWithString:“ぴよまるソフトウェア”
–>  (NSString) “ぴよまる”
set s1 to aStr’s characterAtIndex:0
–>  «data ushr7430»–NG

set subStrRange to aStr’s rangeOfComposedCharacterSequenceAtIndex:0
–>  {​​​​​location:0, ​​​​​length:1​​​}
set bStr to aStr’s substringWithRange:subStrRange
–>  (NSString) “ぴ”–OK

★Click Here to Open This Script 

2015/08/15 ASOCでRTFの内容を読み取って指定文字を置換してファイルに保存する

Cocoaの機能を利用して、既存のRTF(リッチテキストフォーマット)の内容を読み取って、指定文字を置換するAppleScriptです。置換したあとのスタイル付きテキストをファイルに保存するところまでの処理を追加しました。

前バージョンを掲載したところ、(自分的には目的にかなう内容であったものの)Shaneからツッコミ。「ファイルに書かないと置換した内容の確認のしようがないじゃん(意訳)」という指摘により、保存処理を追加しました。

AppleScript名:ASOCでRTFの内容を読み取って指定文字を置換してファイルに保存する
– Created 2015-08-15 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

–Input
set aFile to POSIX path of (choose file of type {“public.rtf”})
set aFilePath to current application’s NSString’s stringWithString:aFile

–Output
set bFile to POSIX path of (choose file name with prompt “Choose replaced new RTF to save (with \”.rtf\” extension)”)
set bFilePath to current application’s NSString’s stringWithString:bFile

–Read RTF to NSData
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:(null) |error|:(missing value)
set astyledLength to theStyledText’s |string|()’s |length|()

–Replace Tag with String
theStyledText’s mutableString()’s replaceOccurrencesOfString:“<name>” withString:“長野谷” options:(current application’s NSCaseInsensitiveSearch) range:(current application’s NSMakeRange(0, astyledLength))

–Convert NSMutableStyledStrings to RTF
set bstyledLength to theStyledText’s |string|()’s |length|()
set bDict to current application’s NSDictionary’s dictionaryWithObject:“NSRTFTextDocumentType” forKey:(current application’s NSDocumentTypeDocumentAttribute)
–>  (NSDictionary) {​​​​​DocumentType:”NSRTFTextDocumentType”​​​}

set bRTF to theStyledText’s RTFFromRange:(current application’s NSMakeRange(0, bstyledLength)) documentAttributes:bDict

–Save to File
bRTF’s writeToFile:bFilePath atomically:true

★Click Here to Open This Script 

2015/01/26 テキストをhexdump(ASOC)v4

NSDataを使ってhexdumpを行うASOCのscriptの、若干の機能追加版です。

文字列の整形にCocoaの機能を使うように変更(データ量が増えた時にも安心できるように)しました。ただ、期待したよりは速くない感じです。

AppleScript名:テキストをhexdump(ASOC)v4
– Created 2015-01-26 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aStr to “あいうえお”

–Hexdump
set theNSString to current application’s NSString’s stringWithString:aStr
set theNSData to theNSString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
set theString to (theNSData’s |description|()’s uppercaseString())

–Remove “< " ">” characters in head and tail
set tLength to (theString’s |length|()) - 2
set aRange to current application’s NSMakeRange(1, tLength)
set theString2 to theString’s substringWithRange:aRange

–Replace Space Characters
set aString to current application’s NSString’s stringWithString:theString2
set bString to aString’s stringByReplacingOccurrencesOfString:” “ withString:“”

set aResList to splitString(bString, 2) as list
–> {​​​​​”E3″, ​​​​​”81″, ​​​​​”82″, ​​​​​”E3″, ​​​​​”81″, ​​​​​”84″, ​​​​​”E3″, ​​​​​”81″, ​​​​​”86″, ​​​​​”E3″, ​​​​​”81″, ​​​​​”88″, ​​​​​”E3″, ​​​​​”81″, ​​​​​”8A”​​​}

–Split NSString in specified aNum characters
on splitString(aText, aNum)
  
  
set aStr to current application’s NSString’s stringWithString:aText
  
if aStr’s |length|() aNum then return aText
  
  
set anArray to current application’s NSMutableArray’s new()
  
set mStr to current application’s NSMutableString’s stringWithString:aStr
  
  
set aRange to current application’s NSMakeRange(0, aNum)
  
  
repeat while (mStr’s |length|()) > 0
    if (mStr’s |length|()) < aNum then
      anArray’s addObject:(current application’s NSString’s stringWithString:mStr)
      
mStr’s deleteCharactersInRange:(current application’s NSMakeRange(0, mStr’s |length|()))
    else
      anArray’s addObject:(mStr’s substringWithRange:aRange)
      
mStr’s deleteCharactersInRange:aRange
    end if
  end repeat
  
  
return (current application’s NSArray’s arrayWithArray:anArray)
  
end splitString

★Click Here to Open This Script 

2015/01/25 テキストをhexdump(ASOC)v2

NSDataを使ってhexdumpを行うASOCのscriptの、若干の機能追加版です。

2文字ごとにペアにして出力するようにしました。

AppleScript名:テキストをhexdump(ASOC)v2
– Created 2015-01-25 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aStr to “あいうえお”
set theNSString to current application’s NSString’s stringWithString:aStr
set theNSData to theNSString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
set theText to text 2 thru -2 of (theNSData’s |description|()’s uppercaseString() as text)
set tList to words of theText
set ttext to tList as string

set aRes to my splitString:ttext everyChar:2
–> {​​​​​”E3″, ​​​​​”81″, ​​​​​”82″, ​​​​​”E3″, ​​​​​”81″, ​​​​​”84″, ​​​​​”E3″, ​​​​​”81″, ​​​​​”86″, ​​​​​”E3″, ​​​​​”81″, ​​​​​”88″, ​​​​​”E3″, ​​​​​”81″, ​​​​​”8A”​​​}

–文字列を指定文字数で分割
on splitString:aText everyChar:aNum
  
  
set aStr to current application’s NSString’s stringWithString:aText
  
if aStr’s |length|() aNum then return aText
  
  
set anArray to current application’s NSMutableArray’s new()
  
set mStr to current application’s NSMutableString’s stringWithString:aStr
  
  
set aRange to current application’s NSMakeRange(0, aNum)
  
  
repeat while (mStr’s |length|()) > 0
    if (mStr’s |length|()) < aNum then
      anArray’s addObject:(current application’s NSString’s stringWithString:mStr)
      
mStr’s deleteCharactersInRange:(current application’s NSMakeRange(0, mStr’s |length|()))
    else
      anArray’s addObject:(mStr’s substringWithRange:aRange)
      
mStr’s deleteCharactersInRange:aRange
    end if
  end repeat
  
  
return (current application’s NSArray’s arrayWithArray:anArray) as list
  
end splitString:everyChar:

★Click Here to Open This Script