— Created 2016-03-12 by Takaaki Naganoya — Modified 2019-02-27 by Takaaki Naganoya — Modified 2020–09-21 by Takaaki Naganoya — 2020 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "AppKit" use framework "SFPSDWriter" –https://github.com/shinyfrog/SFPSDWriter
property |NSURL| : a reference to current application’s |NSURL| property NSString : a reference to current application’s NSString property NSUUID : a reference to current application’s NSUUID property NSImage : a reference to current application’s NSImage property SFPSDWriter : a reference to current application’s SFPSDWriter property NSWorkspace : a reference to current application’s NSWorkspace
property SFPSDResolutionUnitPPI : 1 property SFPSDResolutionUnitPPC : 2
set anWriter to (SFPSDWriter’s alloc()’s initWithDocumentSize:(current application’s CGSizeMake(1200, 400)) andResolution:72.0 andResolutionUnit:(SFPSDResolutionUnitPPI))
set aCount to 1
repeat with yPos from 0 to 400 by 110 repeat with xPos from 0 to 1024 by 110 set aImage to (current application’s NSImage’s alloc()’s initWithSize:{100, 100}) set aColor to current application’s NSColor’s redColor() my drawCircleOnNSIMage(aImage, 100, 0, 0, aColor)
(anWriter’s addLayerWithNSImage:aImage andName:("Layer_" & aCount as string) andOpacity:1.0 andOffset:{x:(xPos as real), y:(yPos as real)}) set aCount to aCount + 1 end repeat end repeat
set aPSD to anWriter’s createPSDData()
set theName to NSUUID’s UUID()’s UUIDString() set pathString to NSString’s stringWithString:("~/Desktop/output_" & theName & ".psd") set newPath to pathString’s stringByExpandingTildeInPath()
aPSD’s writeToFile:newPath atomically:true
# MARK: Call By Reference on drawCircleOnNSIMage(aImage, aRadius, aXpos, aYpos, aColor) set aBezier to generateCircle(aRadius, aXpos, aYpos) of me (aImage)’s lockFocus() aColor’s |set|() aBezier’s fill() –ぬりつぶし (aImage)’s unlockFocus() end drawCircleOnNSIMage
# MARK: circleのBezier曲線を作成して返す on generateCircle(theRadius, x, y) set aRect to current application’s NSMakeRect(x, y, theRadius, theRadius) set aCirCle to current application’s NSBezierPath’s bezierPath() aCirCle’s appendBezierPathWithOvalInRect:aRect return aCirCle end generateCircle
指定アプリケーションのAppleScript用語辞書(sdef)をHTMLに書き出すツール「AS Dictionary」は有用なツールです。もともと、hasがScriptingのための独自機構「objc-appscript」を作ったときの補助ツールでしたが、そのobjc-appscriptそのものは見るべきものがありませんでした(OS X 10.7あたりのOS側の構造改変で動かなくなってプロジェクト終了)。
Mac App StoreではBeta版のXcodeからのバイナリ提出を認めていないため、Universal Binary版のAppleScriptアプリケーションをMac App Storeに提出するためには、このXcode 12.2正式版のリリースを待つ必要があることでしょう。
現時点で先行して、macOS 11.0 Big Sur対応をIntel Mac向けのみで(ARMバイナリなしで)行うことは不可能ではありませんが、あまり意味がないことでしょう。まだRelease前ということもあって、Betaごとに仕様が変わってきています。とくにGUIまわりで。細かなバグもBetaごとに異なるものが見られます。
さて、コンテストに話を戻します。Pixelmator Pro v1.8の試用版を使うことで、同アプリケーションのScriptを書いて試せるとのこと(やっています)。辞書内容は事前に確認していましたが、ツッコミどころがあまりないぐらい、さまざまな機能が載っていました。「え、こんな機能まで乗せてるの?」という謎の充実度を見せており(Pixelmator Pro本体に搭載されていないQRコードの検出機能とか)、AS機能の開発に元AppleのSal Soghoianが協力したという話もうなづけます。
……巨大Scriptで一部のScripterがコンテストを蹂躙することを避けつつ、「このあたり、穴場だよね?」という箇所を埋めてあります。あっと驚く参加者(たぶん、最年少参加者)が優勝をもぎ取って、真の実力者(Edama2さんみたいな)が投稿したScriptが全力でスルーされつつPixelmator Pro Scriptingの肥やしになりそうな、よく考えられたレギュレーションです(コンテストってそういうもんなんで)。
tell front document set allNum to count every slide if allNum < 2 then return –slideの枚数が少なかった場合に処理終了
set curSlide to current slide if allNum = curSlide then return –current slideが末尾だった場合処理終了
set sNum to slide number of curSlide set nextSlide to slide (sNum + 1)
–最初のページ(スライド)からオブジェクトを収集 tell current slide set curObj1 to every image set curObj2 to every group set curObjList to curObj1 & curObj2 if curObjList = {} then return end tell
–次のページ(スライド)からオブジェクトを収集 tell nextSlide set nextObj1 to every image set nextObj2 to every group set nextObjList to nextObj1 & nextObj2 if nextObjList = {} then return end tell
set nexObjRes to calcOverlappedObj(curObjList, nextObjList) of me repeat with i in nexObjRes copy i to {origID, targID} set aOrigObj to contents of item origID of curObjList set aTargObj to contents of item origID of nextObjList set origPos to position of aOrigObj set position of aTargObj to origPos end repeat
set current slide to slide sNum end tell end tell
–与えられた2つのリストに入っているKeynoteオブジェクトの矩形座標が重なっているものをIDペアで出力する –同時に複数のオブジェクトが重なっていないことが前提 on calcOverlappedObj(objList1, objList2) tell application "Keynote" –最初のページのオブジェクトからオブジェクトIDとNSRectからなるリストを作成 set objRecList1 to {} set aCount to 1 repeat with i in objList1 if contents of i is not equal to {} then set {x1, y1} to position of i set aRect to {origin:{x:x1, y:y1}, |size|:{|width|:(width of i), |height|:(height of i)}}
set the end of objRecList1 to {objID:aCount, rect:aRect} end if set aCount to aCount + 1 end repeat
–次のページのオブジェクトからオブジェクトIDとNSRectからなるリストを作成 set objRecList2 to {} set aCount to 1 repeat with i in objList2 if contents of i is not equal to {} then set {x1, y1} to position of i set aRect to {origin:{x:x1, y:y1}, |size|:{|width|:(width of i), |height|:(height of i)}}
set the end of objRecList2 to {objID:aCount, rect:aRect} end if set aCount to aCount + 1 end repeat
–最初のページのオブジェクトと次のページのオブジェクトで矩形エリアが重なっているオブジェクトを抽出してそれぞれのIDをペアにしたリストを作成 set matchList to {} repeat with i in objRecList1
set origRect to rect of i set origID to objID of i
repeat with ii in objRecList2
set targRect to rect of ii set targID to objID of ii set tRes to detectRectanglesCollision(origRect, targRect) of me
if tRes = true then set the end of matchList to {origID, targID} end if end repeat
end repeat
return matchList end tell end calcOverlappedObj
–NSRect同士の衝突判定 on detectRectanglesCollision(aRect, bRect) set a1Res to (current application’s NSIntersectionRect(aRect, bRect)) as {record, list} set tmpClass to class of a1Res
if tmpClass = record then –macOS 10.10, 10.11, 10.12 return not (a1Res = {origin:{x:0.0, y:0.0}, |size|:{width:0.0, height:0.0}}) else if tmpClass = list then –macOS 10.13 or later return not (a1Res = {{0.0, 0.0}, {0.0, 0.0}}) end if end detectRectanglesCollision
— Created 2015-11-01 by Takaaki Naganoya — 2015 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "AppKit"
tell application "Finder" if (count every window) = 0 then return tell front window set {xPos, yPos} to position log {xPos, yPos} end tell end tell
set dispID to getPointInWhichScreen(xPos, yPos) of me
–指定座標がどのディスプレイ上に表示されているかをIDで返す(0はじまり。0はメインディスプレイ) on getPointInWhichScreen(xPos, yPos) set dList to getScreensResol() of me
set aPoint to current application’s NSMakePoint(xPos, yPos) set dCount to 0 repeat with i in dList set dRes to current application’s NSPointInRect(aPoint, i) as boolean
if dRes = true then return dCount end if set dCount to dCount + 1 end repeat
return dCount – 1 –ちょっと怪しいが、動作している様子 end getPointInWhichScreen
on getScreensResol() set dispList to (current application’s NSScreen’s screens()) as list set dList to {} repeat with i in dispList set framePref to i’s visibleFrame() set {xPos, yPos} to first item of framePref set theInfo to (i’s deviceDescription()’s NSDeviceSize) as record set a1Rect to {origin:{x:xPos, y:yPos}, |size|:theInfo} set the end of dList to a1Rect end repeat return dList end getScreensResol
— Created 2015-11-02 13:48:32 +0900 by Takaaki Naganoya — 2015 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "QuartzCore"
set aPath to (choose file of type {"com.adobe.pdf"} with prompt "Select PDF to check")
set aRes to my retProtectedPDFPermissions(aPath) –> missing value (パスワードは設定されていない)
–> {openPermission:false, copyPermission:true, printPermission:true, commentPermission:true, contentAccessPermission:true, assemblyPermission:true, docchangePermission:true, formPermission:true}–オープンするためにはパスワードが必要(openPermission)
–指定のPDFにパスワードが設定されているかどうかをチェック on retProtectedPDFPermissions(aPath) set aURL to current application’s |NSURL|’s fileURLWithPath:(POSIX path of aPath) set aPDFdoc to current application’s PDFDocument’s alloc()’s initWithURL:aURL set anEncF to aPDFdoc’s isEncrypted() if anEncF = false then return missing value
set passLocked to aPDFdoc’s unlockWithPassword:""
set cpPerm to aPDFdoc’s allowsCopying() as boolean set prPerm to aPDFdoc’s allowsPrinting() as boolean set cmPerm to aPDFdoc’s allowsCommenting() as boolean set caPerm to aPDFdoc’s allowsContentAccessibility() as boolean set daPerm to aPDFdoc’s allowsDocumentAssembly() as boolean set dcPerm to aPDFdoc’s allowsDocumentChanges() as boolean set ffPerm to aPDFdoc’s allowsFormFieldEntry() as boolean
use AppleScript version "2.4" — Yosemite (10.10) or later use framework "AppKit" use framework "AppleScriptObjC" use framework "CoreFoundation" use framework "Foundation" use scripting additions
on run my testRun() end run
on testRun() set aMainMes to "アプリケーションの選択" set aSubMes to "適切なものを以下からえらんでください"
#ダイアログ内のビューサイズを指定 set aHeight to 384 set aWidth to 512 + 12 –> スクロールバーの分
#アプリケーションフォルダ内のアプリケーションを取得 set aFolder to path to applications folder set aPath to aFolder’s POSIX path set aURL to current application’s NSURL’s fileURLWithPath:aPath
# 指定フォルダの直下のファイルを取得 set filePaths to current application’s NSFileManager’s defaultManager’s ¬ contentsOfDirectoryAtURL:aURL ¬ includingPropertiesForKeys:{current application’s NSURLNameKey} ¬ options:(current application’s NSDirectoryEnumerationSkipsHiddenFiles) ¬ |error|:(missing value)
set filePaths to filePaths as list set thisFileType to "com.apple.application-bundle"
set dataSourceList to {} repeat with anItem in filePaths
set aPath to anItem’s contents’s POSIX path set aURL to (current application’s NSURL’s fileURLWithPath:aPath)
set {aResult, aUTI, aError} to (aURL’s getResourceValue:(reference) ¬ forKey:(current application’s NSURLTypeIdentifierKey) ¬ |error|:(reference))
if (aUTI as text) is thisFileType then set iconImage to (current application’s NSWorkspace’s sharedWorkspace’s iconForFile:aPath) set dict to {fileURL:aURL, icon:iconImage} set dataSourceList’s end to dict end if end repeat
set execButtonTitle to "OK😄"
set dateObj to my chooseItemByCollectionView:aMainMes subMes:aSubMes myWidth:aWidth myHeight:aHeight myDataSource:dataSourceList okTitle:execButtonTitle end testRun
on chooseItemByCollectionView:(aMainMes as text) subMes:(aSubMes as text) myWidth:(aWidth as integer) myHeight:(aHeight as integer) myDataSource:(dataSourceList as list) okTitle:(execButtonTitle as text)
# Script Bundle内のResourcesフォルダを求める set resourcePath to POSIX path of (path to me) & "Contents/Resources/" set theBundle to current application’s NSBundle’s bundleWithPath:resourcePath theBundle’s loadAppleScriptObjectiveCScripts()
# subClasses.scptを呼び出す set DialogCore to current application’s AppDelegate’s new() set fRes to DialogCore’s chooseItemByCollectionView:aMainMes subMes:aSubMes myWidth:aWidth myHeight:aHeight myDataSource:dataSourceList okTitle:execButtonTitle
if fRes is missing value then error number -128 return fRes as list end chooseItemByCollectionView:subMes:myWidth:myHeight:myDataSource:okTitle:
script AppDelegate property parent : class "NSObject"
— IBOutlets property theWindow : missing value
on applicationShouldTerminate:sender return current application’s NSTerminateNow end applicationShouldTerminate:
on applicationShouldTerminateAfterLastWindowClosed:sender return true end applicationShouldTerminateAfterLastWindowClosed:
——————
on applicationWillFinishLaunching:aNotification log my testRun() end applicationWillFinishLaunching:
on testRun() set aMainMes to "アプリケーションの選択" set aSubMes to "適切なものを以下からえらんでください"
#ダイアログ内のビューサイズを指定 set aHeight to 384 set aWidth to 512 + 12 –> スクロールバーの分
#アプリケーションフォルダ内のアプリケーションを取得 set aFolder to path to applications folder set aPath to aFolder’s POSIX path set aURL to current application’s NSURL’s fileURLWithPath:aPath
# 指定フォルダの直下のファイルを取得 set filePaths to current application’s NSFileManager’s defaultManager’s ¬ contentsOfDirectoryAtURL:aURL ¬ includingPropertiesForKeys:{current application’s NSURLNameKey} ¬ options:(current application’s NSDirectoryEnumerationSkipsHiddenFiles) ¬ |error|:(missing value)
set filePaths to filePaths as list set thisFileType to "com.apple.application-bundle"
set dataSourceList to {} repeat with anItem in filePaths
set aPath to anItem’s contents’s POSIX path set aURL to (current application’s NSURL’s fileURLWithPath:aPath)
set {aResult, aUTI, aError} to (aURL’s getResourceValue:(reference) ¬ forKey:(current application’s NSURLTypeIdentifierKey) ¬ |error|:(reference))
if (aUTI as text) is thisFileType then set iconImage to (current application’s NSWorkspace’s sharedWorkspace’s iconForFile:aPath) set dict to {fileURL:aURL, icon:iconImage} set dataSourceList’s end to dict end if end repeat
set execButtonTitle to "OK😄"
set dateObj to my chooseItemByCollectionView:aMainMes subMes:aSubMes myWidth:aWidth myHeight:aHeight myDataSource:dataSourceList okTitle:execButtonTitle end testRun
# アラートダイアログでCollectionViewを表示 property _retrieve_data : missing value on chooseItemByCollectionView:(aMainMes as text) subMes:(aSubMes as text) myWidth:(aWidth as integer) myHeight:(aHeight as integer) myDataSource:(dataSourceList as list) okTitle:(execButtonTitle as text)
set paramObj to {myMessage:aMainMes} set paramObj to paramObj & {mySubMessage:aSubMes} set paramObj to paramObj & {myDataSource:dataSourceList} set paramObj to paramObj & {myWidth:aWidth} set paramObj to paramObj & {myHeight:aHeight} set paramObj to paramObj & {myOKTitile:execButtonTitle}
my performSelectorOnMainThread:"raizeAlert:" withObject:paramObj waitUntilDone:true
if (my _retrieve_data) is missing value then error number -128 return (my _retrieve_data) end chooseItemByCollectionView:subMes:myWidth:myHeight:myDataSource:okTitle:
## retrieve date on raizeAlert:paramObj
set mesText to paramObj’s myMessage as text set infoText to paramObj’s mySubMessage as text set dataSourceList to paramObj’s myDataSource as list set viewWidth to paramObj’s myWidth as integer set viewHeight to paramObj’s myHeight as integer set okButton to paramObj’s myOKTitile as text
# set up view set {thisView, collectionView} to my makeContentView(dataSourceList, viewWidth, viewHeight)
### set up alert tell current application’s NSAlert’s new() addButtonWithTitle_(okButton) addButtonWithTitle_("Cancel") setAccessoryView_(thisView) –setIcon_(aImage) setInformativeText_(infoText) setMessageText_(mesText) tell |window|() setInitialFirstResponder_(thisView) end tell #### show alert in modal loop if runModal() is (current application’s NSAlertSecondButtonReturn) then return end tell
### retrieve data set aIndexSet to collectionView’s selectionIndexes() set theArray to current application’s NSArrayController’s alloc()’s initWithContent:(collectionView’s content()) set chooseItems to ((theArray)’s arrangedObjects()’s objectsAtIndexes:aIndexSet) as list
# reset set _retrieve_data to {}
repeat with anItem in chooseItems set (my _retrieve_data)’s end to anItem’s contents end repeat
return my _retrieve_data end raizeAlert:
# set up view on makeContentView(dataSourceList, viewWidth, viewHeight)
set thisRect to current application’s NSMakeRect(0, 0, viewWidth, viewHeight)
# Viewを作成 tell current application’s NSScrollView’s alloc() tell initWithFrame_(thisRect) setBorderType_(current application’s NSBezelBorder) setDocumentView_(collectionView) setHasHorizontalScroller_(true) setHasVerticalScroller_(true) set baseView to it end tell end tell
return {baseView, collectionView} end makeContentView end script
#MARK: – script YKZView property parent : class "NSView"
set myRect to current application’s NSMakeRect(0, 0, viewItemWidth, viewItemHeight) continue initWithFrame:myRect
set aHeight to viewItemHeight – 10 set aWidth to viewItemWidth – 10 set newRect to current application’s NSMakeRect(5, 5, aWidth, aHeight)
tell current application’s NSImageView’s alloc() tell initWithFrame_(newRect) setImageScaling_(current application’s NSImageScaleProportionallyUpOrDown) setImageAlignment_(current application’s NSImageAlignCenter) set my imageView to it end tell end tell
my addSubview:(my imageView) return me end initWithFrame:
on drawRect:rect if my selected then current application’s NSColor’s redColor()’s |set|() else current application’s NSColor’s controlBackgroundColor()’s |set|() end if current application’s NSRectFill(rect) continue drawRect:rect end drawRect: end script
#MARK: – script YKZCollectionViewItem property parent : class "NSCollectionViewItem"
on loadView() my setView:(current application’s YKZView’s alloc()’s initWithFrame:(current application’s NSZeroRect)) end loadView
on setRepresentedObject:representedObject –continue setRepresentedObject:representedObject if representedObject is missing value then return (my view())’s imageView’s setImage:(representedObject’s icon) end setRepresentedObject:
on setSelected:isSelected set (my view())’s selected to isSelected (my view())’s setNeedsDisplay:true continue setSelected:isSelected end setSelected: end script
set F1 to (aBundle = missing value) as boolean if F1 is not equal to false then return calcIllegular(aPOSIX) of me
set aDict to aBundle’s executableArchitectures() set F2 to (aDict = missing value) as boolean if F2 is equal to true then return calcIllegular(aPOSIX) of me
set aList to (aDict’s valueForKeyPath:"stringValue") as list
set arList to {} repeat with i in aList set j to contents of i
if j = "7" then –NSBundleExecutableArchitectureI386 set the end of arList to "Intel 32" else if j = "18" then –NSBundleExecutableArchitecturePPC set the end of arList to "PPC 32" else if j = "16777223" then –NSBundleExecutableArchitectureX86_64 set the end of arList to "Intel 64" else if j = "16777234" then –NSBundleExecutableArchitecturePPC64 set the end of arList to "PPC 64" else if j = "16777228" then –NSBundleExecutableArchitectureARM64 set the end of arList to "ARM 64" end if end repeat
return arList end chk32Binary
on calcIllegular(aPOSIX) –Old Style Bundle for PPC set sRes to do shell script "file " & quoted form of aPOSIX if sRes contains "Mach-O executable ppc" then return {"PPC 32"} –NSBundleExecutableArchitecturePPC return missing value end calcIllegular
set anApp to choose file of type {“com.apple.application-bundle”} default location (path to applications folder)
set app32 to chk32Binary(anApp) of me
–> true –32bit
–> false –64bit
on chk32Binary(anApp)
set aExec to getAppPropertyFromInfoPlist(anApp, “CFBundleExecutable”) of me
set posixPath to (POSIX path of anApp) & “/Contents/MacOS/” & aExec
set aRes to do shell script “file “ & quoted form of posixPath
log aRes
if aRes contains “Mach-O executable i386” then
return true –32bit
else
return false –64bit
end if
end chk32Binary
on getAppPropertyFromInfoPlist(anAlias, aKey as string)
set aURL to current application’s |NSURL|’s fileURLWithPath:(POSIX path of anAlias)
set aBundle to current application’s NSBundle’s bundleWithURL:aURL
set aDict to aBundle’s infoDictionary()
set vRes to (aDict’s valueForKey:aKey) as string
return vRes as string
end getAppPropertyFromInfoPlist
if uRes is not equal to {} then set the end of fList to contents of i end if end if end repeat return fList end filterAliasListByUTI
–Application path –> Bundle ID on getBundleIDFromPath(aPOSIXpath as string) set aURL to current application’s |NSURL|’s fileURLWithPath:aPOSIXpath set aWorkspace to current application’s NSWorkspace’s sharedWorkspace() set appURL to aWorkspace’s URLForApplicationToOpenURL:aURL set aBundle to current application’s NSBundle’s bundleWithURL:appURL set anID to aBundle’s bundleIdentifier() return anID as string end getBundleIDFromPath
on revealAFileByFinder(aPOSIXpath as string) set pathStr to current application’s NSString’s stringWithString:aPOSIXpath set parentPath to pathStr’s stringByDeletingLastPathComponent() set aRes to current application’s NSWorkspace’s sharedWorkspace()’s selectFile:pathStr inFileViewerRootedAtPath:parentPath end revealAFileByFinder
–Alias –> UTI on getUTIfromPath(anAlias) set aPOSIXpath to POSIX path of anAlias set aURL to current application’s |NSURL|’s fileURLWithPath:aPOSIXpath if aURL = missing value then return missing value set aRes to aURL’s resourceValuesForKeys:{current application’s NSURLTypeIdentifierKey} |error|:(missing value) if aRes = missing value then return missing value return (aRes’s NSURLTypeIdentifierKey) as string end getUTIfromPath
on filterUTIList(aUTIList, aUTIstr) set anArray to NSArray’s arrayWithArray:aUTIList set aPred to NSPredicate’s predicateWithFormat_("SELF UTI-CONFORMS-TO %@", aUTIstr) set bRes to (anArray’s filteredArrayUsingPredicate:aPred) as list return bRes end filterUTIList
use AppleScript
use framework “AppKit”
use framework “Foundation”
use framework “WebKit”
use scripting additions
on run args
if (args’s class) is script then
set myPath to (path to me)’s POSIX path
set resultText to do shell script “osascript “ & myPath’s quoted form
else
my main()
end if
end run
on main()
set mes to “Markdownファイルを選択してください。”
set chooseItems to choose file of type {“net.daringfireball.markdown”} with prompt mes
#
set aScreen to current application’s NSScreen’s mainScreen()
set screenFrame to aScreen’s frame()
set aHeight to current application’s NSHeight(screenFrame)
set aWidth to current application’s NSWidth(screenFrame)
set aHeight to aHeight * 0.845
set aWidth to aWidth * 0.94 / 2
set paramObj to {myMessage:“Markdown preview”}
set paramObj to paramObj & {mySubMessage:“file : “ & chooseItems’s POSIX path}
set paramObj to paramObj & {mdFile:chooseItems}
set paramObj to paramObj & {viewWidth:aWidth}
set paramObj to paramObj & {viewHeight:aHeight}
my performSelectorOnMainThread:“displayMarkdownPreview:” withObject:(paramObj) waitUntilDone:true
end main
# Markdownをダイアログで表示
on displayMarkdownPreview:paramObj
set mesText to myMessage of paramObj as text
set infoText to mySubMessage of paramObj as text
set mdFile to (mdFile of paramObj) as alias
set viewWidth to (viewWidth of paramObj) as integer
set viewHeight to (viewHeight of paramObj) as integer
## HTMLを読み込む
set mePath to path to me
set resPath to (mePath & “Contents:Resources:index.html”) as text
set htmlStr to (read (resPath as alias) as «class utf8») as text
## MDを読み込む
set mdStr to (read mdFile as «class utf8») as text
## MD内に改行があるとうまく読み込まれないので改行を置き換え
set mdStr to current application’s NSString’s stringWithString:mdStr
set mdStr to mdStr’s stringByReplacingOccurrencesOfString:(linefeed) withString:“\\n”
set mdStr to mdStr’s stringByReplacingOccurrencesOfString:“’” withString:“\\’”
## html内の文字を置き換え
set aString to current application’s NSString’s stringWithFormat_(htmlStr, mdStr) as text
log result
## baseURL
set aPath to mdFile’s POSIX path
set baseURL to current application’s NSURL’s fileURLWithPath:aPath
set baseURL to baseURL’s URLByDeletingLastPathComponent()
##
set aConf to current application’s WKWebViewConfiguration’s new()
tell current application’s WKUserContentController’s new()
aConf’s setUserContentController:it
end tell
## WebViewを作成&読み込み
set frameSize to current application’s NSMakeRect(0, 0, viewWidth, viewHeight)
tell current application’s WKWebView’s alloc()
tell initWithFrame_configuration_(frameSize, aConf)
setNavigationDelegate_(me)
setUIDelegate_(me)
loadHTMLString_baseURL_(aString, baseURL)
set theView to it
end tell
end tell
## アイコンの指定
set aImage to current application’s NSWorkspace’s sharedWorkspace()’s iconForFileType:“net.daringfireball.markdown”
current application’s NSRunningApplication’s currentApplication()’s activateWithOptions:0
## set up alert
tell current application’s NSAlert’s new()
addButtonWithTitle_(“Close”)
setAccessoryView_(theView)
setIcon_(aImage)
setInformativeText_(infoText)
setMessageText_(mesText)
tell |window|()
setInitialFirstResponder_(theView)
end tell
### show alert in modal loop
if runModal() is (current application’s NSAlertSecondButtonReturn) then return
end tell
## 後始末
theView’s stopLoading()
set js to “window.open(’about:blank’,’_self’).close();”
theView’s evaluateJavaScript:js completionHandler:(missing value)
set theView to missing value
end displayMarkdownPreview:
return langLocalizedList end getLocalizedLangNameList
on getLangNameWithLocale(langCode, aLocale) set aLangName to (aLocale’s displayNameForKey:(current application’s NSLocaleIdentifier) value:langCode) as string return aLangName end getLangNameWithLocale
return langLocalizedList end getLocalizedLangNameList
on getLangNameWithLocale(langCode, aLocale) set aLangName to (aLocale’s displayNameForKey:(current application’s NSLocaleIdentifier) value:langCode) as string return aLangName end getLangNameWithLocale