クリップボードに入れたproperty宣言文を見た目の描画サイズ(幅)で行単位の並べ替えを行うAppleScriptです。
property文でCocoaのClass名を定義しており、これを整形するために文字数で短いものから長いものへ並べてみたところ、プロポーショナルフォントで表示されるために「美しく」はなりませんでした。実際に仮装画面上でスタイル付きテキストの描画を行って、描画サイズ(幅)を取得して並べ替えを行ってみたものです。
OLD Style AppleScriptの機能の範囲では逆立ちしても実現できない処理内容です。
AppleScript名:クリップボードに入ったproperty宣言部分を見た目の描画サイズ(幅)と文字コードでソート |
— Created 2017-12-08 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.5" use scripting additions use framework "Foundation" use framework "AppKit" property NSFont : a reference to current application’s NSFont property NSData : a reference to current application’s NSData property NSColor : a reference to current application’s NSColor property NSArray : a reference to current application’s NSArray property NSString : a reference to current application’s NSString property NSDictionary : a reference to current application’s NSDictionary property NSPasteboard : a reference to current application’s NSPasteboard property NSCountedSet : a reference to current application’s NSCountedSet property NSMutableArray : a reference to current application’s NSMutableArray property NSSortDescriptor : a reference to current application’s NSSortDescriptor property NSAttributedString : a reference to current application’s NSAttributedString property NSMutableDictionary : a reference to current application’s NSMutableDictionary property NSFontAttributeName : a reference to current application’s NSFontAttributeName property NSKernAttributeName : a reference to current application’s NSKernAttributeName property NSMutableParagraphStyle : a reference to current application’s NSMutableParagraphStyle property NSLigatureAttributeName : a reference to current application’s NSLigatureAttributeName property NSMutableAttributedString : a reference to current application’s NSMutableAttributedString property NSUnderlineStyleAttributeName : a reference to current application’s NSUnderlineStyleAttributeName property NSParagraphStyleAttributeName : a reference to current application’s NSParagraphStyleAttributeName property NSForegroundColorAttributeName : a reference to current application’s NSForegroundColorAttributeName –クリップボードの内容を文字列として取得 set aStr to (the clipboard) as string if aStr = "" then display dialog "No Data in Clipboard" buttons {"OK"} default button 1 return end if –クリップボードの内容をStyled Stringで取得して最頻出フォントを取得 set clipboardAttrStr to getClipboardASStyledText() of me if clipboardAttrStr = missing value then display dialog "Can not get clipboard as Styled String" buttons {"OK"} default button 1 return end if set attrList to getAttributeRunsFromAttrString(clipboardAttrStr) of me set anArray to (NSArray’s arrayWithArray:attrList)’s valueForKeyPath:"fontName" set aFontList to (countItemsByItsAppearance(anArray) of me) set aFontName to theName of first item of aFontList –クリップボードから取得した文字データについて処理 set aList to paragraphs of aStr –行ごとにparseしてlist化 set bList to {} repeat with i in aList set j to contents of i if j ≠ {} then set jList to words of j if jList ≠ {} then if contents of first item of jList = "property" then set curLabel to contents of second item of jList –行をAttributed Stringとして組み立てて、画面描画時の仕上がりサイズを取得 set anAssrStr to makeRTFfromParameters(j, aFontName, 16, -2, 16) of me set aSize to anAssrStr’s |size|() –画面描画時のサイズを取得 if class of aSize = record then set attrStrWidth to width of aSize set attrStrHeight to height of aSize else if class of aSize = list then –macOS 10.13.xのバグ回避 copy aSize to {attrStrWidth, attrStrHeight} end if set the end of bList to {aLabel:curLabel, aCon:j, aWidth:attrStrWidth} end if end if end if end repeat if bList = {} then display dialog "Error" buttons {"OK"} default button 1 return end if –複数キーでソート(書式つきテキストの仕上がりサイズ幅、文字コード順でソート) set aArray to NSArray’s arrayWithArray:bList set desc1 to NSSortDescriptor’s sortDescriptorWithKey:"aWidth" ascending:true set desc2 to NSSortDescriptor’s sortDescriptorWithKey:"aLabel" ascending:true selector:"localizedCaseInsensitiveCompare:" set bArray to aArray’s sortedArrayUsingDescriptors:{desc1, desc2} –ソートしたlist of recordからaCon(元のproperty宣言行そのもの)を一括で取り出す set dArray to (NSMutableArray’s arrayWithArray:bArray)’s valueForKeyPath:"aCon" –listをデリミタつきのテキストに set dStr to retStrFromArrayWithDelimiter(dArray, return) of me set the clipboard to (dStr & return) –1D Listを文字列長でソート v2 on sort1DListByIndicatedStringLength(aList as list, aSortKey as string, sortOrder as boolean) set aArray to NSArray’s arrayWithArray:aList set descLabel1 to NSString’s stringWithString:(aSortKey & ".length") set descLabel2 to NSString’s stringWithString:aSortKey set desc1 to NSSortDescriptor’s sortDescriptorWithKey:descLabel1 ascending:sortOrder set desc2 to NSSortDescriptor’s sortDescriptorWithKey:descLabel2 ascending:true selector:"localizedCaseInsensitiveCompare:" set bArray to aArray’s sortedArrayUsingDescriptors:{desc1, desc2} return bArray as list end sort1DListByIndicatedStringLength –リストを指定デリミタをはさんでテキスト化 on retStrFromArrayWithDelimiter(aList as list, aDelim as string) set anArray to NSArray’s arrayWithArray:aList set aRes to anArray’s componentsJoinedByString:aDelim return aRes as text end retStrFromArrayWithDelimiter –書式つきテキストを組み立てる on makeRTFfromParameters(aStr as string, fontName as string, aFontSize as real, aKerning as real, aLineSpacing as real) set aVal1 to NSFont’s fontWithName:fontName |size|:aFontSize set aKey1 to (NSFontAttributeName) set aVal2 to NSColor’s blackColor() set aKey2 to (NSForegroundColorAttributeName) set aVal3 to aKerning set akey3 to (NSKernAttributeName) set aVal4 to 0 set akey4 to (NSUnderlineStyleAttributeName) set aVal5 to 2 –all ligature ON set akey5 to (NSLigatureAttributeName) set aParagraphStyle to NSMutableParagraphStyle’s alloc()’s init() aParagraphStyle’s setMinimumLineHeight:(aLineSpacing) aParagraphStyle’s setMaximumLineHeight:(aLineSpacing) set akey7 to (NSParagraphStyleAttributeName) set keyList to {aKey1, aKey2, akey3, akey4, akey5, akey7} set valList to {aVal1, aVal2, aVal3, aVal4, aVal5, aParagraphStyle} set attrsDictionary to NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList set attrStr to NSMutableAttributedString’s alloc()’s initWithString:aStr attributes:attrsDictionary return attrStr end makeRTFfromParameters — クリップボードの内容をNSAttributedStringとして取り出して返す on getClipboardASStyledText() set theNSPasteboard to NSPasteboard’s generalPasteboard() set theAttributedStringNSArray to theNSPasteboard’s readObjectsForClasses:({NSAttributedString}) options:(missing value) set theNSAttributedString to theAttributedStringNSArray’s objectAtIndex:0 return theNSAttributedString end getClipboardASStyledText –指定のNSAttributedStringから書式情報をlist of recordで取得 on getAttributeRunsFromAttrString(theStyledText) script aSpd property styleList : {} end script set (styleList of aSpd) to {} —for output set thePureString to theStyledText’s |string|() –pure string from theStyledText set theLength to theStyledText’s |length|() set startIndex to 0 repeat until (startIndex = theLength) set {theAtts, theRange} to theStyledText’s attributesAtIndex:startIndex longestEffectiveRange:(reference) inRange:{startIndex, theLength – startIndex} set aText to (thePureString’s substringWithRange:theRange) as string set aColor to (theAtts’s valueForKeyPath:"NSColor") if aColor is not equal to missing value then set aSpace to aColor’s colorSpace() set aRed to (aColor’s redComponent()) * 255 set aGreen to (aColor’s greenComponent()) * 255 set aBlue to (aColor’s blueComponent()) * 255 set colList to {aRed as integer, aGreen as integer, aBlue as integer} set colStrForFind to (aRed as integer as string) & " " & (aGreen as integer as string) & " " & (aBlue as integer as string) else set colList to {0, 0, 0} set colStrForFind to "0 0 0" end if set aFont to (theAtts’s valueForKeyPath:"NSFont") if aFont is not equal to missing value then set aDFontName to aFont’s displayName() set aDFontSize to aFont’s pointSize() end if set the end of (styleList of aSpd) to {stringVal:aText, colorStr:colStrForFind, colorVal:colList, fontName:aDFontName as string, fontSize:aDFontSize} set startIndex to current application’s NSMaxRange(theRange) end repeat return (styleList of aSpd) end getAttributeRunsFromAttrString –1D Listをアイテムの出現頻度順でソートして返す on countItemsByItsAppearance(aList as list) set aSet to NSCountedSet’s alloc()’s initWithArray:aList set bArray to NSMutableArray’s array() set theEnumerator to aSet’s objectEnumerator() repeat set aValue to theEnumerator’s nextObject() if aValue is missing value then exit repeat bArray’s addObject:(NSDictionary’s dictionaryWithObjects:{aValue, (aSet’s countForObject:aValue)} forKeys:{"theName", "numberOfTimes"}) end repeat set theDesc to NSSortDescriptor’s sortDescriptorWithKey:"numberOfTimes" ascending:false bArray’s sortUsingDescriptors:{theDesc} return bArray as list end countItemsByItsAppearance |
More from my site
(Visited 75 times, 1 visits today)
ASOCからclass名を抽出してpropertyとして展開 v4 – AppleScriptの穴 says:
[…] また、propertyを展開するときに、プロポーショナルフォントで画面描画した際の幅を実際に計算して、文字の描画幅のピクセル数順にソートしています。 […]