Archive for the 'NSNumberFormatter' Category

2016/10/10 数値に3桁セパレータを付加、外して数値に戻す

数値に3桁セパレーター(カンマ)を付加した文字列にするAppleScriptと、そのセパレーター入り文字列を数字に戻すAppleScriptです。

AppleScript名:数値に3桁セパレータを付加、外して数値に戻す
– Created 2016-10-09 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
–http://piyocast.com/as/archives/4253

set aNum to 100000
set aStr to formatNum(aNum) of me
–> "100,000"

set bNum to deFromatNumStr(aStr) of me
–>  100000

on formatNum(theNumber as number)
  set theResult to current application’s NSNumberFormatter’s localizedStringFromNumber:theNumber numberStyle:(current application’s NSNumberFormatterDecimalStyle)
  
return theResult as text
end formatNum

on deFromatNumStr(theNumericString as string)
  set notWantChars to current application’s NSCharacterSet’s characterSetWithCharactersInString:","
  
set targStr to current application’s NSString’s stringWithString:theNumericString
  
set newStr to (targStr’s componentsSeparatedByCharactersInSet:notWantChars)’s componentsJoinedByString:""
  
return ((newStr as string) as number) –Danger in OS X 10.10 (floating point casting bug)
end deFromatNumStr

★Click Here to Open This Script 

2016/07/28 Bookフォルダリネーム

書籍の原稿管理用のAppleScriptです。原稿は章ごとにフォルダ分けしており、

 9999 フォルダ名あるいはファイル名

といったように、仮想ノンブルを前に付けています。この仮想ノンブルで前後関係を制御しており、基本的に数字の大小だけが重要です。

whole.png

最後に1冊分PDFにまとめてビルドするAppleScriptで、書き出し対象のフォルダ以下のMarkdownファイルとPagesのファイルをピックアップし、ファイル名でソート。ソート順は仮想ノンブルによってコントロールされることになります。

Finderの並べ替えを使っているので、シンプルでわかりやすく、使い勝手もよいのですが……ただひとつ難点が。

途中にコンテンツを挿入したい場合にも仮想ノンブルでコントロールしつつ、途中に入るように操作するのですが……場合によってはフォルダおよび書類の仮想ノンブル部分だけリネームする必要が出てきます。

とくに、目下改定作業中の「AppleScript最新リファレンス」のコマンドリファレンス部分は、初版から大幅に改定・補充を行っているため、ひんぱんにリネームが発生して大変です(ーー;;

そこで、こんなScriptを組んでリネーム作業だけ自動化してみました。

Finder上でフォルダを選択して本Scriptを実行すると、選択中のフォルダ名から仮想ノンブルの番号を取得し、

before2.png

内包するフォルダに入っているファイルについても、すべて仮想ノンブル部分を書き換えます。

after2.png

AppleScript名:Bookフォルダリネーム
– Created 2016-07-28 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use framework “Foundation”
use scripting additions
# http://piyocast.com/as/archives/4177

set aStep to 10

tell application “Finder”
  set aSel to (selection as alias list)
end tell
if aSel = {} or aSel = “” then return
set aFol to first item of aSel

tell application “Finder”
  –選択中のフォルダの名称を取得
  
set aName to name of aFol
  
  
–選択中のフォルダに入っている書類を取得
  
tell folder (aFol as string)
    set fList to name of every file as alias list
  end tell
end tell

set {startNumStr, folderNameStr} to parseNumAndString(aName) of me
set startNum to startNumStr as integer

set aRes to sort1DListOrder(fList, true) of me –昇順でファイル名をソート

set aFolStr to aFol as string
set aCount to startNumStr
tell application “Finder”
  repeat with i in aRes
    set anAlias to (aFolStr & (i as string)) as alias
    
set tmpName to name of anAlias
    
    
set {curNum, curName} to parseNumAndString(tmpName) of me
    
set newName to (retZeroPaddingText(aCount, length of curNum) of me) & ” “ & curName
    
    
set name of anAlias to newName
    
    
set aCount to aCount + aStep
  end repeat
end tell

–文字列から先頭にあるとおぼしき数値と、スペースで区切られた後続の文字列を分離する
on parseNumAndString(aName)
  set aOffset to offset of ” “ in aName
  
if aOffset = 0 then error “Illigal Format”
  
set aNum to text 1 thru (aOffset - 1) of aName
  
set aText to text (aOffset + 1) thru -1 of aName
  
return {aNum, aText}
end parseNumAndString

–1D Listをsort / ascOrderがtrueだと昇順ソート、falseだと降順ソート
on sort1DListOrder(theList, aBool)
  set aDdesc to current application’s NSSortDescriptor’s sortDescriptorWithKey:“self” ascending:aBool selector:“localizedCaseInsensitiveCompare:”
  
set theArray to current application’s NSArray’s arrayWithArray:theList
  
return (theArray’s sortedArrayUsingDescriptors:{aDdesc}) as list
end sort1DListOrder

on retZeroPaddingText(aNum as integer, aDigitNum as integer)
  if aNum > (((10 ^ aDigitNum) as integer) - 1) then return “” –Range Check
  
set aFormatter to current application’s NSNumberFormatter’s alloc()’s init()
  
aFormatter’s setUsesGroupingSeparator:false
  
aFormatter’s setAllowsFloats:false
  
aFormatter’s setMaximumIntegerDigits:aDigitNum
  
aFormatter’s setMinimumIntegerDigits:aDigitNum
  
aFormatter’s setPaddingCharacter:“0″
  
set aStr to aFormatter’s stringFromNumber:(current application’s NSNumber’s numberWithFloat:aNum)
  
return aStr as string
end retZeroPaddingText

★Click Here to Open This Script 

2016/07/27 PDFをページごとに分解してJPEGで保存する v2

PDFをページごとに分解してJPEG画像で保存するAppleScriptのアップデート版です。

実際に連番画像に変換して、ePub書類に変換させてみたらページの順序が狂ってしまいました。連番を振るときにゼロパディングしなかったためだとすぐにわかったので、ゼロパディングの処理を追加したものです。

ただし、実際にはこれだと解像度が不足しており、2倍の解像度で出力するように改良して実戦投入(Retina Display環境に配慮しつつ)しました。

AppleScript名:ASOCでPDFをページごとに分解してJPEGで保存する v2
– Created 2014-12-26 by Takaaki Naganoya
– Modified 2015-09-26 by Takaaki Naganoya
– Modified 2015-10-01 by Takaaki Naganoya
– Modified 2016-07-27 by Takaaki Naganoya–save each PDF page as jpeg
– Modified 2016-07-27 by Takaaki Naganoya–added zero padding function
– 2016 Piyomaru Software
# http://piyocast.com/as/archives/4176

use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “Quartz”
use framework “QuartzCore”
use framework “AppKit”

set aHFSPath to (choose file of type {“com.adobe.pdf”} with prompt “ページごとに分解するPDFを指定してください”)
set aPOSIX to POSIX path of aHFSPath
set aURL to (current application’s |NSURL|’s fileURLWithPath:aPOSIX)

set aPOSIXpath to POSIX path of aHFSPath —書き出し先パスをPOSIX pathで用意しておく(あとで加工)

set aPDFdoc to current application’s PDFDocument’s alloc()’s initWithURL:aURL
set pCount to aPDFdoc’s pageCount()

set compFactor to 1.0 – 0.0 = max jpeg compression, 1.0 = none

–PDFをページごとに分割してJPEGでファイル書き出し
repeat with i from 0 to (pCount - 1)
  set thisPage to (aPDFdoc’s pageAtIndex:(i))
  
set thisDoc to (current application’s NSImage’s alloc()’s initWithData:(thisPage’s dataRepresentation()))
  
if thisDoc = missing value then error “Error in getting imagerep from PDF in page:” & (i as string)
  
  
set theData to thisDoc’s TIFFRepresentation()
  
set newRep to (current application’s NSBitmapImageRep’s imageRepWithData:theData)
  
set targData to (newRep’s representationUsingType:(current application’s NSJPEGFileType) |properties|:{NSImageCompressionFactor:compFactor, NSImageProgressive:false})
  
set zText to retZeroPaddingText((i + 1), 4) of me
  
set outPath to addString_beforeExtensionIn_addingExtension_(“_” & zText, aPOSIXpath, “jpg”)
  
  (
targData’s writeToFile:outPath atomically:true) –書き出し
end repeat

–ファイルパス(POSIX path)に対して、文字列(枝番)を追加。任意の拡張子を追加
on addString:extraString beforeExtensionIn:aPath addingExtension:aExt
  set pathString to current application’s NSString’s stringWithString:aPath
  
set theExtension to pathString’s pathExtension()
  
set thePathNoExt to pathString’s stringByDeletingPathExtension()
  
  
set newPath to (thePathNoExt’s stringByAppendingString:extraString)’s stringByAppendingPathExtension:aExt
  
return newPath as string
end addString:beforeExtensionIn:addingExtension:

on retZeroPaddingText(aNum as integer, aDigitNum as integer)
  if aNum > (((10 ^ aDigitNum) as integer) - 1) then return “” –Range Check
  
set aFormatter to current application’s NSNumberFormatter’s alloc()’s init()
  
aFormatter’s setUsesGroupingSeparator:false
  
aFormatter’s setAllowsFloats:false
  
aFormatter’s setMaximumIntegerDigits:aDigitNum
  
aFormatter’s setMinimumIntegerDigits:aDigitNum
  
aFormatter’s setPaddingCharacter:“0″
  
set aStr to aFormatter’s stringFromNumber:(current application’s NSNumber’s numberWithFloat:aNum)
  
return aStr as string
end retZeroPaddingText

★Click Here to Open This Script 

2016/02/10 ASOCでゼロパディング v2

Cocoaの機能を用いて数値に対して指定桁数でゼロパディングを行ってstringで返すAppleScriptの改良版です。

出力指定桁と指定桁から算出される最大値のオーバーチェックを付加しました。

AppleScript名:ASOCでゼロパディング v2
– Created 2016-02-09 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aNum to 4
set aRes to retZeroPaddingText(aNum, 5) of me
–>  ”00004″–OK

set aNum to 12345678
set aRes to retZeroPaddingText(aNum, 5) of me
–>  ”"–range over

on retZeroPaddingText(aNum as integer, aDigitNum as integer)
  if aNum > (((10 ^ aDigitNum) as integer) - 1) then return “” –Range Check
  
set aFormatter to current application’s NSNumberFormatter’s alloc()’s init()
  
aFormatter’s setUsesGroupingSeparator:false
  
aFormatter’s setAllowsFloats:false
  
aFormatter’s setMaximumIntegerDigits:aDigitNum
  
aFormatter’s setMinimumIntegerDigits:aDigitNum
  
aFormatter’s setPaddingCharacter:“0″
  
set aStr to aFormatter’s stringFromNumber:(current application’s NSNumber’s numberWithFloat:aNum)
  
return aStr as string
end retZeroPaddingText

★Click Here to Open This Script 

2016/02/09 ASOCでゼロパディング

Cocoaの機能を用いて数値に対して指定桁数でゼロパディングを行ってstringで返すAppleScriptです。

Pure AppleScriptに対して実行速度の面でさほどメリットがあるわけではありません。単なる練習です。

AppleScript名:ASOCでゼロパディング
– Created 2016-02-09 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aNum to 40
set aRes to retZeroPaddingText(aNum, 5) of me
–>  ”00040″

on retZeroPaddingText(aNum as integer, aDigitNum as integer)
  set offsetFormatter to current application’s NSNumberFormatter’s alloc()’s init()
  
–offsetFormatter’s setNegativeFormat:”-#####”
  
–offsetFormatter’s setPositiveFormat:”#####”
  
offsetFormatter’s setUsesGroupingSeparator:false
  
offsetFormatter’s setAllowsFloats:false
  
offsetFormatter’s setMaximumIntegerDigits:aDigitNum
  
offsetFormatter’s setMinimumIntegerDigits:aDigitNum
  
offsetFormatter’s setPaddingCharacter:“0″
  
set aStr to offsetFormatter’s stringFromNumber:(current application’s NSNumber’s numberWithFloat:aNum)
  
return aStr as string
end retZeroPaddingText

★Click Here to Open This Script 

2015/08/12 ASOCで少数点以下の数値の切り上げ、切り下げ v2

Cocoaの機能を用いて、少数点以下の数値の四捨五入を行うAppleScriptです。

NSNumberFormatterRoundHalfUpで四捨五入ができるのを見つけて、実際にためしてみました。

AppleScript名:ASOCで少数点以下の数値の切り上げ、切り下げ v2
– Created 2015-08-12 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set a to 10.511111
set a1Res to roundingAsTaughtInSchool(a, 1)
–>  10.5

set a2Res to roundingAsTaughtInSchool(a, 2)
–>  10.51

set b to 10.565111
set b1Res to roundingAsTaughtInSchool(b, 1)
–>  10.6

set b2Res to roundingAsTaughtInSchool(b, 2)
–>  10.57

on roundingAsTaughtInSchool(aNum, aDigit as integer)
  set a to aNum as real
  
set aFormatter to current application’s NSNumberFormatter’s alloc()’s init()
  
aFormatter’s setMaximumFractionDigits:aDigit
  
aFormatter’s setRoundingMode:(current application’s NSNumberFormatterRoundHalfUp)
  
set aStr to aFormatter’s stringFromNumber:(current application’s NSNumber’s numberWithFloat:a)
  
return (aStr as text) as real
end roundingAsTaughtInSchool

★Click Here to Open This Script 

2015/08/12 ASOCで少数点以下の数値の切り上げ、切り下げ

Cocoaの機能を用いて、少数点以下の数値の切り上げ、切り下げを行うAppleScriptです。

Pure AppleScriptでround命令ひとつで(正確にいえば、round aVal rounding as taught in schoolといった表現)四捨五入が行えるのに比べるとちょっと面倒な気がします。

AppleScript名:ASOCで少数点以下の数値の切り上げ、切り下げ
– Created 2015-08-12 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set a to 10.511111
set a1Res to roundingDown(a, 1)
–>  10.5

set a2Res to roundingDown(a, 2)
–>  10.51

set b to 10.565111
set b1Res to roundingUp(b, 1)
–>  10.6

set b2Res to roundingUp(b, 2)
–>  10.57

on roundingDown(aNum, aDigit as integer)
  set a to aNum as real
  
set aFormatter to current application’s NSNumberFormatter’s alloc()’s init()
  
aFormatter’s setMaximumFractionDigits:aDigit
  
aFormatter’s setRoundingMode:(current application’s NSNumberFormatterRoundDown)
  
set aStr to aFormatter’s stringFromNumber:(current application’s NSNumber’s numberWithFloat:a)
  
return (aStr as text) as real
end roundingDown

on roundingUp(aNum, aDigit as integer)
  set a to aNum as real
  
set aFormatter to current application’s NSNumberFormatter’s alloc()’s init()
  
aFormatter’s setMaximumFractionDigits:aDigit
  
aFormatter’s setRoundingMode:(current application’s NSNumberFormatterRoundUp)
  
set aStr to aFormatter’s stringFromNumber:(current application’s NSNumber’s numberWithFloat:a)
  
return (aStr as text) as real
end roundingUp

★Click Here to Open This Script 

2015/08/05 ASOCで数値を指定桁でゼロパディング

Cocoaの機能を用いて指定の数値を指定桁でゼロパディングするAppleScriptです。

ゼロパディング、ゼロサプレスともに定番中の定番処理で、

AppleScript名:ASでゼロパディング
set aStr to makeFN(99, 4)
–> “0099″

on makeFN(aNum, aDigit)
  set aText to “00000000000″ & (aNum as text)
  
set aLen to length of aText
  
set aRes to text (aLen - aDigit + 1) thru -1 of aText
  
return aRes
end makeFN

★Click Here to Open This Script 

こんな風に(↑)処理しています。Cocoaでやるとこんな感じ(↓)です。AppleScriptの数値表現の桁数が10桁程度なので、10桁を超える(実際には9桁で指数表示に)数値を処理する場合にメリットが出てくるところでしょうか。

AppleScript名:ASOCで数値を指定桁でゼロパディング
– Created 2015-08-05 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aTEXT to numToZeroPaddingStr(99, 4, “0″)
–>  ”0099″

set aTEXT to numToZeroPaddingStr(99999999, 20, “0″)
–> “00000000000099999999″

–整数の値に指定桁数ゼロパディングして文字列で返す
on numToZeroPaddingStr(aNum as integer, aDigit as integer, paddingChar as text)
  
  
set aNumForm to current application’s NSNumberFormatter’s alloc()’s init()
  
aNumForm’s setPaddingPosition:(current application’s NSNumberFormatterPadBeforePrefix)
  
aNumForm’s setPaddingCharacter:paddingChar
  
aNumForm’s setMinimumIntegerDigits:aDigit
  
  
set bNum to current application’s NSNumber’s numberWithInt:aNum
  
set aStr to aNumForm’s stringFromNumber:bNum
  
  
return aStr as text
  
end numToZeroPaddingStr

★Click Here to Open This Script 

2014/12/04 NSNumberFormatterのテスト

NSNumberFormatterを使って、数値をさまざまな表現形式のテキストに変換してみる実験です。

AppleScriptだと1E10ぐらいで指数表示になってしまいますが、Cocoaの機能を使うと・・・あれ? 「兆」(1,000,000,000,000)はクリアできるものの、「京」(10,000,000,000,000,000)ぐらいで上限に達してしまうようで。

AppleScriptだけで自力で「数値→日本語的数値表現エンコーダー」を作って、無量大数まで対応させた(そこまでしか日本語の中にある数値表現がないので)ことはありますが、無量大数まで対応する数値表現エンコード/デコード能力はCocoaにないことがわかりました(それとも、NSNumberの有効桁数の問題? 有効桁数可変のNSMutableNumberとかないんだろうか)。

「無量大数」って言葉、バカっぽくて好きです。

AppleScript名:NSNumberFormatterのテスト
– Created 2014-12-03 by Takaaki Naganoya
– 2014 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”

set a to 100000
set b to current application’s NSNumberFormatter’s localizedStringFromNumber:a numberStyle:(current application’s NSNumberFormatterNoStyle)
set c to b’s ASify() as string
–> “100000″

set b to current application’s NSNumberFormatter’s localizedStringFromNumber:a numberStyle:(current application’s NSNumberFormatterDecimalStyle)
set c to b’s ASify() as string
–> “100,000″

set b to current application’s NSNumberFormatter’s localizedStringFromNumber:a numberStyle:(current application’s NSNumberFormatterCurrencyStyle)
set c to b’s ASify() as string
–> “\100,000″

set aa to 0.1
set b to current application’s NSNumberFormatter’s localizedStringFromNumber:aa numberStyle:(current application’s NSNumberFormatterPercentStyle)
set c to b’s ASify() as string
–> “10%”

set b to current application’s NSNumberFormatter’s localizedStringFromNumber:a numberStyle:(current application’s NSNumberFormatterScientificStyle)
set c to b’s ASify() as string
–> “1E5″

set b to current application’s NSNumberFormatter’s localizedStringFromNumber:a numberStyle:(current application’s NSNumberFormatterSpellOutStyle)
set c to b’s ASify() as string
–> “十万”

set a to 111111111
set b to current application’s NSNumberFormatter’s localizedStringFromNumber:a numberStyle:(current application’s NSNumberFormatterSpellOutStyle)
set c to b’s ASify() as string
–> “一億千百十一万千百十一”

set a to 9.11111111111E+16
set b to current application’s NSNumberFormatter’s localizedStringFromNumber:a numberStyle:(current application’s NSNumberFormatterSpellOutStyle)
set c to b’s ASify() as string
–> “一京八千十四兆三千九百八十五億九百四十八万千九百八十四”

★Click Here to Open This Script