Menu

Skip to content
AppleScriptの穴
  • Home
  • Products
  • Books
  • Docs
  • Events
  • Forum
  • About This Blog
  • License
  • 仕事依頼

AppleScriptの穴

Useful & Practical AppleScript archive. Click '★Click Here to Open This Script' Link to download each AppleScript

タグ: 10.13savvy

MacDownで編集中のMarkDown書類で見出しが見出し落ちしていないかチェック

Posted on 2月 6, 2018 by Takaaki Naganoya

MacDownで編集中のMarkdown書類をいったんデスクトップにPDF書き出しして、見出しがページ末尾に位置していないか(見出し落ち)をチェックするAppleScriptです。

MacDownのAppleScript対応機能が少ないので、ほとんどAppleScriptだけで処理しています。Cocoaの機能を呼べるようになったので、とくに問題ありません。

MacDownで編集中の最前面のMarkdown書類からパスを取得し、AppleScriptで直接ファイルから内容を読み込み、正規表現で見出し一覧を取得します。

MacDownからGUI Scripting経由でメニューをコントロールしてPDF書き出しを行い、ページ単位でPDFからテキストを抽出。不要な空白文字列などを削除。


▲いわゆる「見出し落ち」の状態。ページ末尾に見出し項目が存在している

各ページのテキストが見出しの内容で終了していれば、結果出力用の変数midashiOchiListに{ページ数, 見出し名称} を追加して出力します。

–> {{2, “対象となるFramework”}}

AppleScript名:MacDownで編集中のMarkDown書類で見出しが見出し落ちしていないかチェック
— Created 2017-08-12 by Takaaki Naganoya
— 2017 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "Quartz"

property NSString : a reference to current application’s NSString
property NSCharacterSet : a reference to current application’s NSCharacterSet
property NSRegularExpression : a reference to current application’s NSRegularExpression
property NSRegularExpressionAnchorsMatchLines : a reference to current application’s NSRegularExpressionAnchorsMatchLines
property NSRegularExpressionDotMatchesLineSeparators : a reference to current application’s NSRegularExpressionDotMatchesLineSeparators

set docName to getFrontmostMarkdownDocName() of me
if docName = false then return

set newName to repFileNameExtension(docName, ".pdf") of me
set newPath to (POSIX path of (path to desktop)) & newName
set dRes to deleteItemAt(newPath) of me –前回実行時にデスクトップに残った同名のPDFを削除する

–Markdownのソースを元ファイルから直接読み出す
set docSourcePath to getFrontmostMarkdownFullPath() of me
set aStr to (read (docSourcePath as alias) as «class utf8»)

–getHeader List
set aList to retHeaders(aStr) of me

–Export Markdown to PDF (desktop folder)
macDownForceSave() of me

set tList to textInPDFinEachPage(newPath) of me

set pCount to 1
set midashOchiList to {}
repeat with i in tList
  set j to (contents of i) as string
  
  
repeat with ii in aList
    set jj to (contents of second item of ii) as string
    
–set jj2 to replaceText(jj, "(", "(") of me
    
–set jj3 to replaceText(jj2, ")", ")") of me
    
    
if (j ends with jj) then
      set the end of midashOchiList to {pCount, jj}
    end if
  end repeat
  
set pCount to pCount + 1
end repeat

return midashOchiList

on retHeaders(aCon)
  set tList to {}
  
set regStr to "^#{1,6}[^#]*?$"
  
  
set headerList to my findPattern:regStr inString:aCon
  
repeat with i in headerList
    set j to contents of i
    
set regStr2 to "^#{1,6}[^#]*?"
    
set headerLevel to length of first item of (my findPattern:regStr2 inString:j)
    
set tmpHeader1 to text (headerLevel + 1) thru -1 in j
    
–ヘッダーの前後から空白文字をトリミング
    
set tmpHeader2 to trimWhiteSpaceFromHeadAndTail(tmpHeader1) of me
    
    
–ヘッダー部でPDF書き出ししたときに全角文字が半角文字に置換されてしまうケースに対処
    
set tmpHeader3 to replaceText(tmpHeader2, "(", "(") of me
    
set tmpHeader4 to replaceText(tmpHeader3, ")", ")") of me
    
    
set the end of tList to {headerLevel, tmpHeader4}
  end repeat
  
  
return tList
end retHeaders

on findPattern:thePattern inString:theString
  set theOptions to ((NSRegularExpressionDotMatchesLineSeparators) as integer) + ((NSRegularExpressionAnchorsMatchLines) as integer)
  
set theRegEx to NSRegularExpression’s regularExpressionWithPattern:thePattern options:theOptions |error|:(missing value)
  
set theFinds to theRegEx’s matchesInString:theString options:0 range:{location:0, |length|:length of theString}
  
set theFinds to theFinds as list — so we can loop through
  
set theResult to {} — we will add to this
  
set theNSString to NSString’s stringWithString:theString
  
repeat with i from 1 to count of items of theFinds
    set theRange to (item i of theFinds)’s range()
    
set end of theResult to (theNSString’s substringWithRange:theRange) as string
  end repeat
  
return theResult
end findPattern:inString:

–指定文字列の前後から空白をトリミング
on trimWhiteSpaceFromHeadAndTail(aStr as string)
  set aString to NSString’s stringWithString:aStr
  
set bString to aString’s stringByTrimmingCharactersInSet:(NSCharacterSet’s whitespaceAndNewlineCharacterSet())
  
return bString as list of string or string –as anything
end trimWhiteSpaceFromHeadAndTail

–ファイル名の拡張子を置換する
on repFileNameExtension(origName, newExt)
  set aName to current application’s NSString’s stringWithString:origName
  
set theExtension to aName’s pathExtension()
  
if (theExtension as string) is not equal to "" then
    set thePathNoExt to aName’s stringByDeletingPathExtension()
    
set newName to (thePathNoExt’s stringByAppendingString:newExt)
  else
    set newName to (aName’s stringByAppendingString:newExt)
  end if
  
  
return newName as string
end repFileNameExtension

on textInPDFinEachPage(thePath)
  set aList to {}
  
  
set anNSURL to (current application’s |NSURL|’s fileURLWithPath:thePath)
  
set theDoc to current application’s PDFDocument’s alloc()’s initWithURL:anNSURL
  
  
set theCount to theDoc’s pageCount() as integer
  
  
repeat with i from 1 to theCount
    set thePage to (theDoc’s pageAtIndex:(i – 1))
    
set curStr to (thePage’s |string|())
    
set curStr2 to curStr’s decomposedStringWithCanonicalMapping() –Normalize Text with NFC
    
set targString to string id 13 & string id 10 & string id 32 & string id 65532 –Object Replacement Character
    
set bStr to (curStr2’s stringByTrimmingCharactersInSet:(current application’s NSCharacterSet’s characterSetWithCharactersInString:targString))
    
set the end of aList to (bStr as string)
  end repeat
  
  
return aList
end textInPDFinEachPage

–注意!! ここでGUI Scriptingを使用。バージョンが変わったときにメニュー階層などの変更があったら書き換え
on macDownForceSave()
  activate application "MacDown"
  
tell application "System Events"
    tell process "MacDown"
      — File > Export > PDF
      
click menu item 2 of menu 1 of menu item 14 of menu 1 of menu bar item 3 of menu bar 1
      
      
–Go to Desktop Folder
      
keystroke "d" using {command down}
      
      
–Save Button on Sheet
      
click button 1 of sheet 1 of window 1
    end tell
  end tell
end macDownForceSave

on getFrontmostMarkdownDocName()
  tell application "MacDown"
    set dList to every document
    
set dCount to count every item of dList
    
if dCount is not equal to 1 then
      display notification "Markdown document is not only one."
      
return false
    end if
    
    
tell document 1
      set docName to name
    end tell
    
return docName
  end tell
end getFrontmostMarkdownDocName

on getFrontmostMarkdownFullPath()
  tell application "MacDown"
    tell document 1
      set aProp to properties
    end tell
  end tell
  
  
set aPath to (file of aProp)
end getFrontmostMarkdownFullPath

–任意のデータから特定の文字列を置換
on replaceText(origData, origText, repText)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to {origText}
  
set origData to text items of origData
  
set AppleScript’s text item delimiters to {repText}
  
set origData to origData as text
  
set AppleScript’s text item delimiters to curDelim
  
–set b to origData as text
  
return origData
end replaceText

–指定のPOSIX pathのファイルを強制削除(あってもなくてもいい)
on deleteItemAt(aPOSIXpath)
  set theNSFileManager to current application’s NSFileManager’s defaultManager()
  
set theResult to theNSFileManager’s removeItemAtPath:(aPOSIXpath) |error|:(missing value)
  
return (theResult as integer = 1) as boolean
end deleteItemAt

★Click Here to Open This Script 

Posted in GUI Scripting Markdown PDF Text | Tagged 10.11savvy 10.12savvy 10.13savvy MacDown | Leave a comment

指定のMarkdown書類を走査して指定文字列(Question)をカウント

Posted on 2月 6, 2018 by Takaaki Naganoya
AppleScript名:指定のMarkdown書類を走査して指定文字列(Question)をカウント
— Created 2017-11-14 by Takaaki Naganoya
— 2017 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set origPath to (choose file of type {"net.daringfireball.markdown"} with prompt "処理対象のMarkdown書類を選択")

set aText to (read origPath as «class utf8»)
set aFreq to retFrequency(aText, ">Q") of me

–指定文字列内の指定キーワードの出現回数を取得する
on retFrequency(origText, aKeyText)
  set aRes to parseByDelim(origText, aKeyText) of me
  
return ((count every item of aRes) – 1)
end retFrequency

on parseByDelim(aData, aDelim)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set dList to text items of aData
  
set AppleScript’s text item delimiters to curDelim
  
return dList
end parseByDelim

★Click Here to Open This Script 

Posted in Markdown Text | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

listからHTML Tableの生成 v2

Posted on 2月 6, 2018 by Takaaki Naganoya
AppleScript名:listからHTML Tableの生成 v2
— Created 2017-02-24 by Takaaki Naganoya
— 2017 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set aList to {{"1", "2", "3"}, {"3", "4", "5"}, {"5", "6", "7"}}
set aHeader to "<html><head><title>First</title><style>table , td, table , tr, th{border:1px solid #333333;padding:2px;}</style></head><body><table ><tr><th>Col1</th><th>Col2</th><th>Col3</th><th>Col4</th><th>Col5</th></tr>"
set aTable to "<tr><td>%@</td><td> </td><td>%@</td><td>%@</td><td>%@</td></tr>"
set aFooter to "</table></body></html>"

set aHTMLres to retTableHTML(aList, aHeader, aTable, aFooter) of me

on retTableHTML(aList, aHeaderHTML, aTableHTML, aFooterHTML)
  set allHTML to current application’s NSMutableString’s stringWithString:aHeaderHTML
  
  
set aCounter to 1
  
repeat with i in aList
    set j to contents of i
    
set tmpList to (current application’s NSArray’s arrayWithArray:j)
    
set aRowHTML to current application’s NSString’s stringWithFormat_(aTableHTML, (aCounter as string), tmpList’s objectAtIndex:0, tmpList’s objectAtIndex:1, tmpList’s objectAtIndex:2)
    (
allHTML’s appendString:aRowHTML)
    
set aCounter to aCounter + 1
  end repeat
  
  (
allHTML’s appendString:aFooterHTML)
  
  
allHTML
end retTableHTML

★Click Here to Open This Script 

Posted in Text | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

指定のテキストからHTMLタグを除去(NSScanner)

Posted on 2月 6, 2018 by Takaaki Naganoya
AppleScript名:指定のテキストからHTMLタグを除去(NSScanner)
— Created 2016-12-12 by Shane Stanley
— Modified 2016-12-14 by edama2
— Modified 2017-11-28 by Takaaki Naganoya
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

–set aStr to read (choose file)
set aStr to "<a>repeat</a>~end repeat<BR>"
set aRes to (trimStrFromTo(aStr, "<", ">") of me)
–>  "repeat~end repeat"

on trimStrFromTo(aParamStr, fromStr, toStr)
  set theScanner to current application’s NSScanner’s scannerWithString:aParamStr
  
set anArray to current application’s NSMutableArray’s array()
  
  
repeat until (theScanner’s isAtEnd as boolean)
    set {theResult, theKey} to theScanner’s scanUpToString:fromStr intoString:(reference)
    
    
theScanner’s scanString:fromStr intoString:(missing value)
    
set {theResult, theValue} to theScanner’s scanUpToString:toStr intoString:(reference)
    
if theValue is missing value then set theValue to ""
    
    
theScanner’s scanString:toStr intoString:(missing value)
    
    
anArray’s addObject:theValue
  end repeat
  
  
if anArray’s |count|() = 0 then return aParamStr
  
  
copy aParamStr to curStr
  
repeat with i in (anArray as list)
    set curStr to repChar(curStr, fromStr & i & toStr, "") of me
  end repeat
  
  
return curStr
end trimStrFromTo

on repChar(aStr, targStr, repStr)
  set aString to current application’s NSString’s stringWithString:aStr
  
set bString to aString’s stringByReplacingOccurrencesOfString:targStr withString:repStr
  
set cString to bString as string
  
return cString
end repChar

★Click Here to Open This Script 

Posted in Text | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

ASOCでUUID文字列を取得する

Posted on 2月 6, 2018 by Takaaki Naganoya
AppleScript名:ASOCでUUID文字列を取得する
— Created 2015-08-14 by Takaaki Naganoya
— 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set aUUID to current application’s NSUUID’s UUID()
–>  (__NSConcreteUUID) <__NSConcreteUUID 0x7f87d814d000> 6737A4CD-D509-42F5-BD0C-DB894127424D

set aStr to aUUID’s UUIDString()
–>  (NSString) "6737A4CD-D509-42F5-BD0C-DB894127424D"

set bStr to aStr as text
–> "6737A4CD-D509-42F5-BD0C-DB894127424D"

★Click Here to Open This Script 

Posted in Text | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

伏字文字列を作成する v4

Posted on 2月 6, 2018 by Takaaki Naganoya
AppleScript名:伏字文字列を作成する v4
— Created 2015-09-09 by Shane Stanley
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set aStr to "これは秘密のInformationです。" –Alphabet & Numeric以外でも置換可能
set bStr to makeUnprintableChars(aStr)
–>  "xxxxxxXxxxxxxxxxxxx。"

on makeUnprintableChars(aStr)
  set anNSString to current application’s NSString’s stringWithString:aStr
  
set anNSString to anNSString’s stringByReplacingOccurrencesOfString:"[\\p{Lu}\\p{Lt}\\p{Nd}]" withString:"X" options:(current application’s NSRegularExpressionSearch) range:{0, anNSString’s |length|()}
  
set anNSString to anNSString’s stringByReplacingOccurrencesOfString:"[\\p{Ll}\\p{Lm}\\p{Lo}]" withString:"x" options:(current application’s NSRegularExpressionSearch) range:{0, anNSString’s |length|()}
  
return anNSString as text
end makeUnprintableChars

★Click Here to Open This Script 

Posted in Text | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

ASOCでテキストを行ごとにparseしてNSArrayに

Posted on 2月 6, 2018 by Takaaki Naganoya
AppleScript名:ASOCでテキストを行ごとにparseしてNSArrayに
— Created 2015-07-02 17:32:59 +0900 by Takaaki Naganoya
— 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set aText to "ABCDE
01234
あいうえお
かきくけこ
さしすせそ
たちつてと
なにぬねの"

set aArray to parseParagraphs(aText) of me
set aRes to countArrayItems(aArray) of me
–>  7

–最初のアイテム
set bRes to retFirstObject(aArray) of me
–>  (NSString) "ABCDE"

–最後のアイテム
set cRes to retLastObject(aArray) of me
–>  (NSString) "なにぬねの"

–指定アイテム目のアイテム
set dRes to retNthObject(aArray, 2) of me
–>  (NSString) "01234"

–テキストを改行でParseしてArrayに
on parseParagraphs(a)
  
  
set aStr to current application’s NSString’s stringWithString:a
  
set retStr to current application’s NSString’s stringWithString:(string id 10)
  
set aRes to (aStr’s componentsSeparatedByString:retStr) –parse strings by return
  
  
return aRes
  
end parseParagraphs

–与えられた配列の要素数を返す
on countArrayItems(aArray)
  set aRes to aArray’s |count|()
  
return aRes
end countArrayItems

–与えられた配列の最初の要素を返す
on retFirstObject(aArray)
  set a to aArray’s firstObject()
  
return a
end retFirstObject

–与えられた配列の最後の要素を返す
on retLastObject(aArray)
  set a to aArray’s lastObject()
  
return a
end retLastObject

–与えられた配列の指定アイテム目の要素を返す
on retNthObject(aArray, nTh)
  if nTh ≤ 0 then return false
  
  
set aIndex to current application’s NSNumber’s numberWithInt:((nTh – 1) as integer)
  
set aRes to aArray’s objectAtIndex:aIndex
  
  
return aRes
end retNthObject

★Click Here to Open This Script 

Posted in Text | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

ASOCで文字を逆順に v2(CJK文字などマルチバイト対応)

Posted on 2月 6, 2018 by Takaaki Naganoya
AppleScript名:ASOCで文字を逆順に v2(CJK文字などマルチバイト対応)
— 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 

Posted in Text | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

ASOCで文字列の長さを求める

Posted on 2月 6, 2018 by Takaaki Naganoya
AppleScript名:ASOCで文字列の長さを求める
— Created 2015-09-02 by Takaaki Naganoya
— 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set a to current application’s NSMutableString’s stringWithString:"あいうえお"
set b to a’s |length|()
–>  5

★Click Here to Open This Script 

Posted in Text | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

バージョン番号文字列からメジャーバージョンを取り出し数値として返す v4

Posted on 2月 6, 2018 by Takaaki Naganoya
AppleScript名:バージョン番号文字列からメジャーバージョンを取り出し数値として返す v4
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set a to "10.0.1"
set b to retMajorVersionNumber(a) of me
–> 10

set a to "9.10"
set b to retMajorVersionNumber(a) of me
–> 9

–バージョン番号文字列からメジャーバージョンを取り出し数値として返す
on retMajorVersionNumber(a)
  
  
set aStr to current application’s NSString’s stringWithString:a
  
–> "10.0.1" (NSString)
  
  
set aRes to (aStr’s componentsSeparatedByString:".")
  
–> {"10","0","1"} (NSArray)
  
  
set bRes to aRes’s firstObject()
  
–> "10" (NSString)
  
  
set cRes to bRes’s integerValue()
  
–> 10
  
  
return cRes as integer
  
end retMajorVersionNumber

★Click Here to Open This Script 

Posted in Text | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

ASOCでbase64エンコード、デコード v3

Posted on 2月 6, 2018 by Takaaki Naganoya
AppleScript名:ASOCでbase64エンコード、デコード v3
— Created 2015-07-27 by Takaaki Naganoya
— Updated 2015-07-28 by Shane Stanley
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set aStr to "ぴよまるソフトウェアPiyomaru Software"
set theNSString to current application’s NSString’s stringWithString:aStr
set theNSData to theNSString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
set bStr to base64StringFromFileString(aStr) of me
return bStr
–>  "44G044KI44G+44KL44K944OV44OI44Km44Kn44KiUGl5b21hcnUgU29mdHdhcmU="

set aFilePath to POSIX path of (choose file)
base64StringFromFileAtPath(aFilePath) of me

–Base 64 Decode
on detaFromBase64String(aStr)
  set dataFrom64 to current application’s NSData’s alloc()’s initWithBase64EncodedString:aStr options:(current application’s NSDataBase64DecodingIgnoreUnknownCharacters)
  
set aStr to current application’s NSString’s alloc()’s initWithData:dataFrom64 encoding:(current application’s NSUTF8StringEncoding)
  
return aStr as text –stringではなくtext
end detaFromBase64String

–Base64 Encode
on base64StringFromFileAtPath(aFilePath)
  set aDataFromFile to current application’s NSData’s dataWithContentsOfFile:aFilePath
  
set aBase64EncStr to aDataFromFile’s base64EncodedStringWithOptions:(current application’s NSDataBase64Encoding64CharacterLineLength)
  
return aBase64EncStr as text
end base64StringFromFileAtPath

–Base64 Encode
on base64StringFromFileString(aString)
  set bString to current application’s NSString’s stringWithString:aString
  
set aData to bString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aBase64EncStr to aData’s base64EncodedStringWithOptions:(current application’s NSDataBase64Encoding64CharacterLineLength)
  
return aBase64EncStr as text
end base64StringFromFileString

★Click Here to Open This Script 

Posted in Text | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

テキストによるプログレスインジケータ作成 v2

Posted on 2月 6, 2018 by Takaaki Naganoya
AppleScript名:テキストによるプログレスインジケータ作成 v2
set aList to {50, 24} –max-num, cur-num
set cList to {".", "o"}
set aRes to retProgressChar(aList, cList) of me
–> "ooooo….."

on retProgressChar(aList, cList)
  set barCharLen to 10
  
  
set allNum to item 1 of aList
  
set doneNum to item 2 of aList
  
if doneNum > allNum then return ""
  
  
set oneStep to 100 / allNum
  
set curStep to doneNum * oneStep
  
  
set stringBar to (curStep / barCharLen)
  
set stringBar2 to round stringBar rounding as taught in school
  
  
–未処理アイテム数
  
set notYet to barCharLen – stringBar2
  
  
set notYetChar to contents of item 1 of cList
  
set doneChar to contents of item 2 of cList
  
  
set notYetText to makeCharRep(notYet, notYetChar) of me
  
set doneText to makeCharRep(stringBar2, doneChar) of me
  
  
set aText to doneText & notYetText
  
return aText
  
end retProgressChar

–指定文字を指定回数連結したテキストを返す
on makeCharRep(aNum, aChar)
  set aText to ""
  
repeat aNum times
    set aText to aText & aChar
  end repeat
  
return aText
end makeCharRep

★Click Here to Open This Script 

Posted in Text | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

同じ文字を指定回数繰り返して出力

Posted on 2月 6, 2018 by Takaaki Naganoya
AppleScript名:同じ文字を指定回数繰り返して出力

retSeriesOfSameChar("絆", 30)

on retSeriesOfSameChar(aChar, aCount)
  set outStr to ""
  
repeat with i from 1 to aCount
    set outStr to outStr & aChar
  end repeat
end retSeriesOfSameChar

★Click Here to Open This Script 

Posted in Text | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

Unicodeの文字をNormalizeする

Posted on 2月 6, 2018 by Takaaki Naganoya

UTF-8の文字列を、NFD/NFKD/NFC/NFKCの各正規化形式で正規化し、チェックのためのhexdumpするAppleScriptです。

NSStringの状態でNFD/NFKD/NFC/NFKCの各正規化形式で正規化して、そのままAppleScriptのstringに「as string」でcastしても、その正規化の状態は維持されます。

外部から他のOS上で作成したデータを取り込んで扱う場合に、文字列であっても正規化形式が異なるパターンがあります。実際に、PDFから文字列を取り出して、そのまま処理したところ同じ文字列なのに照合できないというケースがありました。その場合に、本Scriptで利用している正規化処理で明示的にいったん処理してからAppleScriptのstringにcastしたところ問題なく扱えました。

問題があった場合には、まずHexdumpして文字列の内容がどのようになっているかをチェックしています。目に見える文字が同じなのにプログラム側からは同じデータとして判定できないという例は、たまにある話なので。

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 

Posted in Text | Tagged 10.11savvy 10.12savvy 10.13savvy | 1 Comment

デコードしたQRコードのメールデータの各フィールドを取り出す v2.2

Posted on 2月 6, 2018 by Takaaki Naganoya
AppleScript名:デコードしたQRコードのメールデータの各フィールドを取り出す v2.2
— Created 2016-12-12 by Shane Stanley
— Modified 2016-12-14 by edama2
— Modified 2017-01-12 by Takaaki Naganoya
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set aStr to "こんにちは、ぴよまるです

MATMSG:TO:hiyoko@piyocast.com;SUB:たいとる;BODY:ほんぶん;;

Takaaki Naganoya
XXX-XXXX-XXXX

iPhoneから送信"

set aDict to (parseStrByParamlabelAndTail(aStr, "MATMSG:", ":", ";") of me)

set eMailAddrs to (aDict’s valueForKey:"TO") as string
–>  "hiyoko@piyocast.com"
set aSubject to (aDict’s valueForKey:"SUB") as string
–>  "たいとる"
set aBody to (aDict’s valueForKey:"BODY") as string
–>  "ほんぶん"

on parseStrByParamlabelAndTail(aParamStr, aDataHeader, aParamLabel, aParamTail)
  set theScanner to current application’s NSScanner’s scannerWithString:aParamStr
  
set aDict to current application’s NSMutableDictionary’s |dictionary|()
  
  
—Skip over the data header
  
set {theResult, theKey} to theScanner’s scanUpToString:aDataHeader intoString:(reference)
  
if theResult as boolean = false then return false –Error: Data header is not present
  
  
theScanner’s scanString:aDataHeader intoString:(missing value)
  
  
repeat until (theScanner’s isAtEnd as boolean)
    — terminate check, return the result (aDict) to caller
    
set {theResult, theKey} to theScanner’s scanUpToString:aParamLabel intoString:(reference)
    
    
— skip over separator
    
theScanner’s scanString:aParamLabel intoString:(missing value)
    
set {theResult, theValue} to theScanner’s scanUpToString:aParamTail intoString:(reference)
    
if theValue is missing value then set theValue to ""
    
    
— skip over separator
    
theScanner’s scanString:aParamTail intoString:(missing value)
    
    
aDict’s setObject:theValue forKey:theKey
  end repeat
  
  
return aDict
end parseStrByParamlabelAndTail

★Click Here to Open This Script 

Posted in Text | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

指定言語のスペルチェックを行い、候補文を返す

Posted on 2月 6, 2018 by Takaaki Naganoya
AppleScript名:指定言語のスペルチェックを行い、候補文を返す
— Created 2015-12-18 by Takaaki Naganoya
— 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

set aText to "This is a penz."
set spRes to spellCheckingInSpecifiedLanguage(aText, "English") of me
–>  {missed:"penz", suggestionList:{"This Is A Pens", "This Is A Pend", "This Is A Penh", "This Is A Penn", "This Is A Pent", "This is a pen"}}

set aText to "Applele"
set spRes to spellCheckingInSpecifiedLanguage(aText, "English") of me
–> {missed:"Applele", suggestionList:{"Apple", "Apples", "Appeal", "Appalled", "Appellate"}}

set aText to "Applele"
set spRes to spellCheckingInSpecifiedLanguage(aText, "French") of me
–>  {​​​​​missed:"Applele", ​​​​​suggestionList:{​​​​​​​"Appelle", ​​​​​​​"Appelée", ​​​​​​​"Appelles"​​​​​}​​​}

set spRes to spellCheckingInSpecifiedLanguage(aText, "fr") of me
–>  {missed:"Applele", suggestionList:{"Appelle", "Appelée", "Appelles"}}

on spellCheckingInSpecifiedLanguage(aText, aLang)
  
  
set aStr to current application’s NSString’s stringWithString:aText
  
set aChecker to current application’s NSSpellChecker’s sharedSpellChecker()
  
aChecker’s setLanguage:aLang
  
  
set aMisspelledRange to aChecker’s checkSpellingOfString:aStr startingAt:0
  
if aMisspelledRange’s |length|() = 0 then return missing value
  
  
–Get Misspelled String  
  
set aMisString to (aStr’s substringWithRange:aMisspelledRange) as text
  
  
–Get Suggestion
  
set aSugList to (aChecker’s guessesForWord:aStr) as list
  
–>  {​​​​​"This Is A Pens", ​​​​​"This Is A Pend", ​​​​​"This Is A Penh", ​​​​​"This Is A Penn", ​​​​​"This Is A Pent", ​​​​​"This is a pen"​​​}
  
  
return {missed:aMisString, suggestionList:aSugList}
end spellCheckingInSpecifiedLanguage

★Click Here to Open This Script 

Posted in Text | Tagged 10.11savvy 10.12savvy 10.13savvy Spell check | Leave a comment

英文のスペルチェックを行い、候補文を返す

Posted on 2月 6, 2018 by Takaaki Naganoya
AppleScript名:英文のスペルチェックを行い、候補文を返す
— Created 2015-12-18 by Takaaki Naganoya
— 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

set aText to "This is a penz."
set spRes to spellChecking(aText) of me
–>  {missed:"penz", suggestionList:{"This Is A Pens", "This Is A Pend", "This Is A Penh", "This Is A Penn", "This Is A Pent", "This is a pen"}}

set aText to "AppleScript"
set spRes to spellChecking(aText) of me
–>  missing value

set aText to "Applele"
set spRes to spellChecking(aText) of me
–> {missed:"Applele", suggestionList:{"Apple", "Apples", "Appeal", "Appalled", "Appellate"}}

on spellChecking(aText)
  set aStr to current application’s NSString’s stringWithString:aText
  
set aChecker to current application’s NSSpellChecker’s sharedSpellChecker()
  
set aMisspelledRange to aChecker’s checkSpellingOfString:aStr startingAt:0
  
if aMisspelledRange’s |length|() = 0 then return missing value
  
  
–Get Misspelled String  
  
set aMisString to (aStr’s substringWithRange:aMisspelledRange) as text
  
  
–Get Suggestion
  
set aSugList to (aChecker’s guessesForWord:aStr) as list
  
–>  {​​​​​"This Is A Pens", ​​​​​"This Is A Pend", ​​​​​"This Is A Penh", ​​​​​"This Is A Penn", ​​​​​"This Is A Pent", ​​​​​"This is a pen"​​​}
  
  
return {missed:aMisString, suggestionList:aSugList}
end spellChecking

★Click Here to Open This Script 

Posted in Text | Tagged 10.11savvy 10.12savvy 10.13savvy Spell check | Leave a comment

NSSpellCheckerでスペルチェック可能な言語の一覧リストを取得_v2

Posted on 2月 6, 2018 by Takaaki Naganoya
AppleScript名:NSSpellCheckerでスペルチェック可能な言語の一覧リストを取得_v2
— Created 2015-12-18 by Takaaki Naganoya
— 2015 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set aChecker to current application’s NSSpellChecker’s sharedSpellChecker()
set langList to (aChecker’s availableLanguages()) as list
–>  {​​​​​"en", ​​​​​"en_GB", ​​​​​"en_AU", ​​​​​"en_CA", ​​​​​"en_IN", ​​​​​"en_SG", ​​​​​"fr", ​​​​​"da", ​​​​​"de", ​​​​​"es", ​​​​​"it", ​​​​​"nl", ​​​​​"nb", ​​​​​"pl", ​​​​​"pt_BR", ​​​​​"pt_PT", ​​​​​"fi", ​​​​​"sv", ​​​​​"tr", ​​​​​"ru", ​​​​​"ko"​​​}

set langNameList to {}
repeat with i in langList
  set j to contents of i
  
–set aLocale to (current application’s NSLocale’s alloc()’s initWithLocaleIdentifier:j)
  
set aLocale to current application’s NSLocale’s currentLocale()
  
  
set aLocName to (aLocale’s displayNameForKey:(current application’s NSLocaleIdentifier) value:j)
  
set cntLocs to (aLocale’s displayNameForKey:(current application’s NSLocaleLanguageCode) value:j)
  
  
set cntName to getCountryNameFromLanguageCode(j) of me
  
  
set the end of langNameList to {aLocName as string, cntName as text, cntLocs as text}
end repeat

return langNameList
–>  {​​​​​{​​​​​​​"英語", ​​​​​​​"アメリカ合衆国", ​​​​​​​"英語"​​​​​}, ​​​​​{​​​​​​​"英語 (イギリス)", ​​​​​​​"イギリス", ​​​​​​​"英語"​​​​​}, ​​​​​{​​​​​​​"英語 (オーストラリア)", ​​​​​​​"オーストラリア", ​​​​​​​"英語"​​​​​}, ​​​​​{​​​​​​​"英語 (カナダ)", ​​​​​​​"カナダ", ​​​​​​​"英語"​​​​​}, ​​​​​{​​​​​​​"英語 (インド)", ​​​​​​​"インド", ​​​​​​​"英語"​​​​​}, ​​​​​{​​​​​​​"英語 (シンガポール)", ​​​​​​​"シンガポール", ​​​​​​​"英語"​​​​​}, ​​​​​{​​​​​​​"フランス語", ​​​​​​​"フランス", ​​​​​​​"フランス語"​​​​​}, ​​​​​{​​​​​​​"デンマーク語", ​​​​​​​"デンマーク", ​​​​​​​"デンマーク語"​​​​​}, ​​​​​{​​​​​​​"ドイツ語", ​​​​​​​"ドイツ", ​​​​​​​"ドイツ語"​​​​​}, ​​​​​{​​​​​​​"スペイン語", ​​​​​​​"スペイン", ​​​​​​​"スペイン語"​​​​​}, ​​​​​{​​​​​​​"イタリア語", ​​​​​​​"イタリア", ​​​​​​​"イタリア語"​​​​​}, ​​​​​{​​​​​​​"オランダ語", ​​​​​​​"オランダ", ​​​​​​​"オランダ語"​​​​​}, ​​​​​{​​​​​​​"ノルウェー語(ブークモール)", ​​​​​​​"ノルウェー", ​​​​​​​"ノルウェー語(ブークモール)"​​​​​}, ​​​​​{​​​​​​​"ポーランド語", ​​​​​​​"ポーランド", ​​​​​​​"ポーランド語"​​​​​}, ​​​​​{​​​​​​​"ポルトガル語 (ブラジル)", ​​​​​​​"ブラジル", ​​​​​​​"ポルトガル語"​​​​​}, ​​​​​{​​​​​​​"ポルトガル語 (ポルトガル)", ​​​​​​​"ポルトガル", ​​​​​​​"ポルトガル語"​​​​​}, ​​​​​{​​​​​​​"フィンランド語", ​​​​​​​"フィンランド", ​​​​​​​"フィンランド語"​​​​​}, ​​​​​{​​​​​​​"スウェーデン語", ​​​​​​​"スウェーデン", ​​​​​​​"スウェーデン語"​​​​​}, ​​​​​{​​​​​​​"トルコ語", ​​​​​​​"トルコ", ​​​​​​​"トルコ語"​​​​​}, ​​​​​{​​​​​​​"ロシア語", ​​​​​​​"ロシア", ​​​​​​​"ロシア語"​​​​​}, ​​​​​{​​​​​​​"韓国語", ​​​​​​​"大韓民国", ​​​​​​​"韓国語"​​​​​}​​​}

on getCountryNameFromLanguageCode(aCode)
  –http://www.benricho.org/translate/countrycode.html  
  
if aCode is equal to "en" then
    set aCode to aCode & "_US"
  else if aCode is equal to "fr" then
    set aCode to aCode & "_FR"
  else if aCode is equal to "da" then
    set aCode to aCode & "_DK"
  else if aCode is equal to "de" then
    set aCode to aCode & "_DE"
  else if aCode is equal to "es" then
    set aCode to aCode & "_ES"
  else if aCode is equal to "it" then
    set aCode to aCode & "_IT"
  else if aCode is equal to "nl" then
    set aCode to aCode & "_NL"
  else if aCode is equal to "nb" then
    set aCode to aCode & "_NO"
  else if aCode is equal to "pl" then
    set aCode to aCode & "_PL"
  else if aCode is equal to "fi" then
    set aCode to aCode & "_FI"
  else if aCode is equal to "sv" then
    set aCode to aCode & "_SE"
  else if aCode is equal to "tr" then
    set aCode to aCode & "_TR"
  else if aCode is equal to "ru" then
    set aCode to aCode & "_RU"
  else if aCode is equal to "ko" then
    set aCode to aCode & "_KR"
  else if aCode is equal to "ja" then
    set aCode to aCode & "_JP"
  end if
  
  
set aLocale to current application’s NSLocale’s currentLocale()
  
set aLoc to (current application’s NSLocale’s alloc()’s initWithLocaleIdentifier:aCode)
  
set aLocCode to aLoc’s objectForKey:(current application’s NSLocaleCountryCode)
  
set aLocName to aLocale’s displayNameForKey:(current application’s NSLocaleCountryCode) value:aLocCode
  
  
return aLocName
  
end getCountryNameFromLanguageCode

★Click Here to Open This Script 

Posted in Text | Tagged 10.11savvy 10.12savvy 10.13savvy Spell check | Leave a comment

articlereducerのじっけん(Japanese)

Posted on 2月 6, 2018 by Takaaki Naganoya

–> articlereducer.framework

AppleScript名:articlereducerのじっけん(Japanese)
— Created 2017-06-28 by Takaaki Naganoya
— 2017 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "articlereducer" –https://github.com/EthanArbuckle/articlereducer

set aStr to "ライター/編集者仲間である友人と雑談していたところ、自然言語処理がいろいろ使えそうなシーンが見えてきました。彼によると、Twitter上で過去記事の紹介ツイートを行いたいが、何も関係ないところに唐突に記事紹介のツイートを投げても不自然だし、興味を持たれにくいので、時事ネタと関連する記事を紹介する仕組みを作れないだろうか、という話になりました。

そこで、比較的鮮度および注目度が高いと思われる「ニュース記事」から固有名詞だけを抽出し、その固有名詞にどのぐらい世間的な注目が集まっているかを判定できると、そのキーワードに関連する過去記事をツイートしやすくなるかもしれないと考えました。

apitoreのREST APIには、ニュースフィードを提供するもの、形態素解析を行うもの、Twitter検索を行うものなどがあり、これらを組み合わせるとできそうな感じがしてきました。

→ Playing with rest api

実際に試してみたところ、ニュースフィードからニュース記事本文を抽出するのは(RSS Feedに本文の冒頭部分が含まれていないケースもあるので、結局記事のサイトを見に行って本文を抽出する必要がある)けっこう大変で、タイトル(題名)のみ処理することに。

次に、タイトルの文章を形態素解析して、「固有名詞」だけを抽出してみました。これは別に難しくもなんともありません。さらに、入り組んだrecordから目的のデータを取り出すのは、AppleScriptでもCocoaの機能を使えば造作もありません。NSDictionaryからvalueForKeyPath:でオブジェクトパスを記述して抽出すれば、データ取り出しのために長々とループ処理で記述する必要はありません。

次の段階は、その時点における「注目度」の計算です。仮にTwitter全体を1つの「世間」とみなし、Twitter上で拡散されていたりお気に入りに入れられる回数の高い単語は、比較的「注目度」が高いものだろうという仮説を立てました。

→ キーワードの言語ごとのTwitter発言内容集計

そこで、ニュースのタイトルから抽出した固有名詞をTwitterで検索し、それぞれの固有名詞がTweet上でどの程度リツイートされたか、お気に入りに入れられたかを計算してみました。これについては、コストの問題からREST APIではなくローカルのmacOS上で動作するAppleScript用Twitterクライアント「TwitterScripter」を呼び出すことにしました。apitore上の各種REST APIは無料で試用できますが、呼び出し回数が増えれば料金がかかるため、その部分を節約することが目的です。TwitterScripterを使用することによるデメリットは、それ自体が並列処理に対応していないこと。Mac上で(AppleScriptによる)並列処理を行ってTwitter検索を行う場合には、直接Twitterの(割と整理されていない)APIを直接呼び出すか、apitore上のREST APIを呼び出すしかなさそうです。

→ AS.Parallel

指定のキーワード(固有名詞)を含むツイートをTwitter上で検索し、それぞれがどの程度リツイートされたか、お気に入りに入れられたかを実際に数値化。その数値をもとにキーワードのランキングを計算することができました。

一応、「活性度の高い」≒「注目度の高い」キーワードを計算できたわけです。ここまでのプログラムはすでに実稼働状態にあり、「こんな(へんな)単語が注目されてるのかー!」という未知の単語のピックアップに成功しています。

ただし、これでは目的を50%しか達成できていません。

この「注目度の高いキーワード」と「過去記事」の間をブリッジする必要があるからです。もう少しわかりやすくいえば、「カール」という本日注目度急上昇中のキーワードがありますが、この「カール」という固有名詞で過去記事を検索したところで、まったく異なる単語の一部がたまたま偶然ひっかかってヒットする程度で、過去記事が超絶的にヒットしにくいことが予想されます(グスタフ・カールとかザンスカール帝国とかカール自走臼砲とかパリダカールラリーとか)。

この「カール」を「スナック菓子」という上位概念に変換し、さらにスナック菓子に所属する単語を取得して、それらの単語で検索できるとよいでしょう(菓子、和菓子など)。このあたりは個人的に「スター・クエリー」と昔から呼んでいるもので、与えられたキーワードから類似・関連するキーワードを複数生成して検索することで、ヒットする確率を高める仕組みです。GoogleやYouTubeでもおそらく類似の機構が検索エンジンに実装されており、入力した単語以外でもヒットするようになっているようです(とくにYouTube)。

apitoreでも日本語Word.netのデータを利用して類義語や上位概念の言葉を計算できるようになっていますが、日本語の基本的な語句に特化しており、実際に試してみたところ「カール」「ガンダム」といった商品名などから類義語や上位概念を求める用途に向いていないことがわかりました。これらの計算を行うためには、Wikipediaのデータからカテゴリを取得できれば、やりやすくなるものと思われます。"

set aCond to current application’s EACondensor’s alloc()’s initWithText:aStr
aCond’s setAverageThreshold:(1.0 as real)
set shortStr to (aCond’s condensedString()) as string
–>  "ライター/編集者仲間である友人と雑談していたところ、自然言語処理がいろいろ使えそうなシーンが見えてきました。彼によると、Twitter上で過去記事の紹介ツイートを行いたいが、何も関係ないところに唐突に記事紹介のツイートを投げても不自然だし、興味を持たれにくいので、時事ネタと関連する記事を紹介する仕組みを作れないだろうか、という話になりました。そこで、比較的鮮度および注目度が高いと思われる「ニュース記事」から固有名詞だけを抽出し、その固有名詞にどのぐらい世間的な注目が集まっているかを判定できると、そのキーワードに関連する過去記事をツイートしやすくなるかもしれないと考えました。apitoreのREST APIには、ニュースフィードを提供するもの、形態素解析を行うもの、Twitter検索を行うものなどがあり、これらを組み合わせるとできそうな感じがしてきました。→ Playing with rest api実際に試してみたところ、ニュースフィードからニュース記事本文を抽出するのは(RSS Feedに本文の冒頭部分が含まれていないケースもあるので、結局記事のサイトを見に行って本文を抽出する必要がある)けっこう大変で、タイトル(題名)のみ処理することに。次に、タイトルの文章を形態素解析して、「固有名詞」だけを抽出してみました。これは別に難しくもなんともありません。さらに、入り組んだrecordから目的のデータを取り出すのは、AppleScriptでもCocoaの機能を使えば造作もありません。NSDictionaryからvalueForKeyPath:でオブジェクトパスを記述して抽出すれば、データ取り出しのために長々とループ処理で記述する必要はありません。次の段階は、その時点における「注目度」の計算です。仮にTwitter全体を1つの「世間」とみなし、Twitter上で拡散されていたりお気に入りに入れられる回数の高い単語は、比較的「注目度」が高いものだろうという仮説を立てました。→ キーワードの言語ごとのTwitter発言内容集計そこで、ニュースのタイトルから抽出した固有名詞をTwitterで検索し、それぞれの固有名詞がTweet上でどの程度リツイートされたか、お気に入りに入れられたかを計算してみました。これについては、コストの問題からREST APIではなくローカルのmacOS上で動作するAppleScript用Twitterクライアント「TwitterScripter」を呼び出すことにしました。apitore上の各種REST APIは無料で試用できますが、呼び出し回数が増えれば料金がかかるため、その部分を節約することが目的です。TwitterScripterを使用することによるデメリットは、それ自体が並列処理に対応していないこと。Mac上で(AppleScriptによる)並列処理を行ってTwitter検索を行う場合には、直接Twitterの(割と整理されていない)APIを直接呼び出すか、apitore上のREST APIを呼び出すしかなさそうです。→ AS. "

★Click Here to Open This Script 

Posted in Text | Tagged 10.11savvy 10.12savvy 10.13savvy | Leave a comment

要約(Summarize)のじっけん

Posted on 2月 6, 2018 by Takaaki Naganoya
AppleScript名:要約(Summarize)のじっけん
— Created 2016-11-15 by Takaaki Naganoya
— 2016 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set piyoText to "githubで公開されているオープンソースのフレームワーク「HTTPServerKit」(By David Thorpe氏)を呼び出して、簡易http(Web)サーバー機能を起動するAppleScriptです。

AppleScriptとWeb CGIのつながりは割と昔(Classic Mac OS 7の時代)からあったのですが、Macの1U Server機(Xserve)が廃止になり、Mac OS X ServerがOSからツール集的な位置付けに後退。macOS 10.8ですでにMac OS Xの標準機能としての「Web共有」はGUI画面上から消えました。

MacをWebサーバーにするような使い方は、作っている方も使う方もあまり重視しなくなってきたともいえますが(WebObjectsで稼働し続けているiTunes Storeをのぞく)、局地的かつ限定された用途において、他のOSプラットフォームからMac内の機能を共有するようなケースでは、使えてほしいものです。

そうしたニーズを受けてか、github上で探してみるといろいろ「簡易Webサーバー」的なプロジェクトを見ることができます。本、HTTPServerKitもそのうちのひとつです。

スクリプトエディタ上で呼び出して処理が終わったら終了、というようなバッチ処理的なありがちなAppleScriptの運用スタイルとは相入れませんが、常駐アプレットとして運用する場合やXcode上で作成するCocoa-AppleScriptアプレットでは利用できるはずです。

本サンプルでは、ホームディレクトリ下の「サイト」(~/Sites)フォルダをDoc Rootに、8081をポート番号に指定してWebサーバー(thttpd)を起動し、60秒間httpのリクエストを受け付け、Webサーバーを終了させます。

すでに、「サイト」フォルダが存在していること、同フォルダ内に「index.html」ファイルが存在していることを前提にしているため、OS X 10.12をクリーンインストールした環境ではファイルが存在せずにうまく動かない可能性もあります(Sitesフォルダが存在しない場合には自動作成しています)。

注意すべき点は、起動したhttpサーバー(thttpd)は、明示的に終了(stop())を行わないと、どんどんプロセスが追加で起動されてしまい、AppleScript側に正しくログなどを返さないようになってしまうことです。毎回、こまめにstop()を呼び出しましょう。

実際にこうして呼び出して評価してみると、やや機能が素朴すぎるきらいがあり、このHTTPServerKitが決定版になるかと言われると、ちょっとつらい気もします。http経由でファイル転送なども行いたいですし、何らかのプログラム呼び出しインタフェースは欲しい気がします。

ただ、ラジオ番組を録音してmp3に変換し、LAN上でiPhoneなどにPodcastとして配信するような用途(ありがち)だと、このぐらいの機能レベルのソフトウェアが合っているようにも見えます。

また、AppleScriptでOAuth2.0の認証を行うような場合に、認証後に表示させるredirect URIについて、「http://localhost」などと指定させたりしますが、もっと気の利いた表示を行うために本Scriptを併用して指定のHTMLを強制表示させるような用途にも使えそうです(redirect_uri:”http://localhost:8081″ のように)。

LAN上の他のOSのマシンからMacを操作させることを目的として、簡易httpサーバーソフトウェアをいろいろと物色しています。ポート番号を指定する機能がないと、デフォルトで起動しているhttpdとコンフリクトを起こしてしまうので、ポート番号指定機能は必須の条件です。

なお、HTTPServerKit.frameworkのビルドは、githubからプロジェクトをダウンロードしてXcodeでいろいろ試しても、ビルドディレクトリを変更したり、日本語を含まないパス上にプロジェクトを移動させたりしても、エラー終了してしまいました(出来がよくない?)。

実際に試す場合には、ビルドされたバイナリをダウンロードするほかないと思われます。AppleScriptの実行前にフレームワークのバイナリを~/Library/Frameworksに入れておいてください。"

set bText to summarizeInSpecifiedChars(piyoText, 400)

on summarizeInSpecifiedChars(piyoText as string, aLimit as integer)
  if length of piyoText ≥ aLimit then
    set pLen to paragraphs of piyoText
    
    
repeat with i from 1 to (length of pLen) by 1
      set bCon to (summarize piyoText in i) as string
      
set p2Len to length of bCon
      
if p2Len ≥ aLimit then
        if i = 1 then
          set i to 1
        else
          set i to i – 1
        end if
        
exit repeat
      end if
    end repeat
    
    
return (summarize piyoText in i)
    
  else
    return piyoText
  end if
end summarizeInSpecifiedChars

★Click Here to Open This Script 

Posted in Text | Tagged 10.11savvy 10.12savvy 10.13savvy | 1 Comment

Post navigation

  • Older posts
  • Newer posts

電子書籍(PDF)をオンラインストアで販売中!

Google Search

Popular posts

  • 開発機としてM2 Mac miniが来たのでガチレビュー
  • macOS 15, Sequoia
  • 指定のWordファイルをPDFに書き出す
  • Pages本執筆中に、2つの書類モード切り替えに気がついた
  • Numbersで選択範囲のセルの前後の空白を削除
  • メキシカンハットの描画
  • Pixelmator Pro v3.6.4でAppleScriptからの操作時の挙動に違和感が
  • AdobeがInDesign v19.4からPOSIX pathを採用
  • AppleScriptによる並列処理
  • Safariで「プロファイル」機能を使うとAppleScriptの処理に影響
  • Cocoa Scripting Course 続刊計画
  • macOS 14.xでScript Menuの実行速度が大幅に下がるバグ
  • AppleScript入門③AppleScriptを使った「自動化」とは?
  • Keynote/Pagesで選択中の表カラムの幅を均等割
  • macOS 15でも変化したText to Speech環境
  • デフォルトインストールされたフォント名を取得するAppleScript
  • macOS 15 リモートApple Eventsにバグ?
  • AppleScript入門① AppleScriptってなんだろう?
  • macOS 14で変更になったOSバージョン取得APIの返り値
  • Keynoteで2階層のスライドのタイトルをまとめてテキスト化

Tags

10.11savvy (1101) 10.12savvy (1242) 10.13savvy (1391) 10.14savvy (587) 10.15savvy (438) 11.0savvy (283) 12.0savvy (212) 13.0savvy (194) 14.0savvy (147) 15.0savvy (132) CotEditor (66) Finder (51) iTunes (19) Keynote (117) NSAlert (61) NSArray (51) NSBitmapImageRep (20) NSBundle (20) NSButton (34) NSColor (53) NSDictionary (28) NSFileManager (23) NSFont (21) NSImage (41) NSJSONSerialization (21) NSMutableArray (63) NSMutableDictionary (22) NSPredicate (36) NSRunningApplication (56) NSScreen (30) NSScrollView (22) NSString (119) NSURL (98) NSURLRequest (23) NSUTF8StringEncoding (30) NSView (33) NSWorkspace (20) Numbers (76) Pages (55) Safari (44) Script Editor (27) WKUserContentController (21) WKUserScript (20) WKWebView (23) WKWebViewConfiguration (22)

カテゴリー

  • 2D Bin Packing
  • 3D
  • AirDrop
  • AirPlay
  • Animation
  • AppleScript Application on Xcode
  • Beginner
  • Benchmark
  • beta
  • Bluetooth
  • Books
  • boolean
  • bounds
  • Bug
  • Calendar
  • call by reference
  • check sum
  • Clipboard
  • Cocoa-AppleScript Applet
  • Code Sign
  • Color
  • Custom Class
  • date
  • dialog
  • diff
  • drive
  • Droplet
  • exif
  • file
  • File path
  • filter
  • folder
  • Font
  • Font
  • GAME
  • geolocation
  • GUI
  • GUI Scripting
  • Hex
  • History
  • How To
  • iCloud
  • Icon
  • Image
  • Input Method
  • Internet
  • iOS App
  • JavaScript
  • JSON
  • JXA
  • Keychain
  • Keychain
  • Language
  • Library
  • list
  • Locale
  • Localize
  • Machine Learning
  • Map
  • Markdown
  • Menu
  • Metadata
  • MIDI
  • MIME
  • Natural Language Processing
  • Network
  • news
  • Noification
  • Notarization
  • Number
  • Object control
  • OCR
  • OSA
  • parallel processing
  • PDF
  • Peripheral
  • PRODUCTS
  • QR Code
  • Raw AppleEvent Code
  • Record
  • rectangle
  • recursive call
  • regexp
  • Release
  • Remote Control
  • Require Control-Command-R to run
  • REST API
  • Review
  • RTF
  • Sandbox
  • Screen Saver
  • Script Libraries
  • sdef
  • search
  • Security
  • selection
  • shell script
  • Shortcuts Workflow
  • Sort
  • Sound
  • Spellchecker
  • Spotlight
  • SVG
  • System
  • Tag
  • Telephony
  • Text
  • Text to Speech
  • timezone
  • Tools
  • Update
  • URL
  • UTI
  • Web Contents Control
  • WiFi
  • XML
  • XML-RPC
  • イベント(Event)
  • 未分類

アーカイブ

  • 2025年5月
  • 2025年4月
  • 2025年3月
  • 2025年2月
  • 2025年1月
  • 2024年12月
  • 2024年11月
  • 2024年10月
  • 2024年9月
  • 2024年8月
  • 2024年7月
  • 2024年6月
  • 2024年5月
  • 2024年4月
  • 2024年3月
  • 2024年2月
  • 2024年1月
  • 2023年12月
  • 2023年11月
  • 2023年10月
  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年6月
  • 2023年5月
  • 2023年4月
  • 2023年3月
  • 2023年2月
  • 2023年1月
  • 2022年12月
  • 2022年11月
  • 2022年10月
  • 2022年9月
  • 2022年8月
  • 2022年7月
  • 2022年6月
  • 2022年5月
  • 2022年4月
  • 2022年3月
  • 2022年2月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年10月
  • 2021年9月
  • 2021年8月
  • 2021年7月
  • 2021年6月
  • 2021年5月
  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年6月
  • 2020年5月
  • 2020年4月
  • 2020年3月
  • 2020年2月
  • 2020年1月
  • 2019年12月
  • 2019年11月
  • 2019年10月
  • 2019年9月
  • 2019年8月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年11月
  • 2018年10月
  • 2018年9月
  • 2018年8月
  • 2018年7月
  • 2018年6月
  • 2018年5月
  • 2018年4月
  • 2018年3月
  • 2018年2月

https://piyomarusoft.booth.pm/items/301502

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org

Forum Posts

  • 人気のトピック
  • 返信がないトピック

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org
Proudly powered by WordPress
Theme: Flint by Star Verte LLC