[PDFKit] PDFを文字検索して、ヒットした文字列にアンダーライン注釈を入れる(v3検索方法を変更findStringにした)
AppleScript サンプルコード
行番号 | ソース |
---|---|
001 | #!/usr/bin/env osascript |
002 | ----+----1----+----2----+-----3----+----4----+----5----+----6----+----7 |
003 | (* |
004 | v3 最適化されていないPDFで注釈が反映されない場合があるので |
005 | 中間ファイルで最適化をしてから検索するように変更した |
006 | その分時間はかかるが入力に依存がなくなるのでいいかなと |
007 | com.cocolog-nifty.quicktimer.icefloe *) |
008 | ----+----1----+----2----+-----3----+----4----+----5----+----6----+----7 |
009 | use AppleScript version "2.8" |
010 | use framework "Foundation" |
011 | use framework "AppKit" |
012 | use framework "PDFKit" |
013 | use scripting additions |
014 | property refMe : a reference to current application |
015 | set appFileManager to refMe's NSFileManager's defaultManager() |
016 | |
017 | |
018 | ################################## |
019 | #設定項目 |
020 | set strAnnotAuther to ("車寅次郎") as text |
021 | set strAnnotName to ("検索結果ハイライト") as text |
022 | set strAnnotContents to ("検索結果") as text |
023 | #ハイライトの色 RGBの場合 |
024 | #set ocidSetColor to (refMe's NSColor's colorWithSRGBRed:(0.4392) green:(0.8196) blue:(0.7764) alpha:(0.85)) |
025 | #ハイライトの色 CMYKの場合 |
026 | set ocidSetColor to (refMe's NSColor's colorWithDeviceCyan:(0.0) magenta:(0.2) yellow:(1) black:(0.0) alpha:(0.85)) |
027 | |
028 | ################################### |
029 | # |
030 | set strReadString to doGetPasteboard() |
031 | set aliasIconPath to doGetAppIconAliasFilePath("com.apple.Preview") |
032 | set strName to (name of current application) as text |
033 | if strName is "osascript" then |
034 | tell application "SystemUIServer" to activate |
035 | else |
036 | tell current application to activate |
037 | end if |
038 | # |
039 | set strTitle to ("検索語句を入力してください") as text |
040 | set strMes to ("検索語句を入力 単語") as text |
041 | set recordResult to (display dialog strMes with title strTitle default answer strReadString buttons {"キャンセル", "OK"} default button "OK" cancel button "キャンセル" giving up after 30 with icon aliasIconPath without hidden answer) |
042 | if (gave up of recordResult) is true then |
043 | return "時間切れです" |
044 | else if (button returned of recordResult) is "キャンセル" then |
045 | return "キャンセルです" |
046 | else |
047 | set strReturnedText to (text returned of recordResult) as text |
048 | #注釈にコンテンツとしてセットする |
049 | set strAnnotContents to (strAnnotContents & ": " & strReturnedText) |
050 | end if |
051 | |
052 | ################################## |
053 | #改行 タブ除去 |
054 | set ocidResponseText to refMe's NSString's stringWithString:(strReturnedText) |
055 | set ocidTextM to refMe's NSMutableString's alloc()'s initWithCapacity:(0) |
056 | ocidTextM's appendString:(ocidResponseText) |
057 | ##改行除去 |
058 | set ocidTextM to ocidTextM's stringByReplacingOccurrencesOfString:("\n") withString:("") |
059 | set ocidTextM to ocidTextM's stringByReplacingOccurrencesOfString:("\r") withString:("") |
060 | ##タブ除去 |
061 | set ocidTextM to ocidTextM's stringByReplacingOccurrencesOfString:("\t") withString:("") |
062 | set strSearchString to ocidTextM as text |
063 | |
064 | |
065 | ############################# |
066 | ###ダイアログを前面に出す |
067 | set strName to (name of current application) as text |
068 | if strName is "osascript" then |
069 | tell application "Finder" to activate |
070 | else |
071 | tell current application to activate |
072 | end if |
073 | ############ デフォルトロケーション |
074 | set appFileManager to refMe's NSFileManager's defaultManager() |
075 | set ocidURLsArray to (appFileManager's URLsForDirectory:(refMe's NSDesktopDirectory) inDomains:(refMe's NSUserDomainMask)) |
076 | set ocidDesktopDirPathURL to ocidURLsArray's firstObject() |
077 | set aliasDesktopDirPath to (ocidDesktopDirPathURL's absoluteURL()) as alias |
078 | |
079 | ############UTIリスト |
080 | set listUTI to {"com.adobe.pdf"} |
081 | set strMes to ("PDFファイルを選んでください") as text |
082 | set strPrompt to ("PDFファイルを選んでください") as text |
083 | try |
084 | set aliasFilePath to (choose file strMes with prompt strPrompt default location (aliasDesktopDirPath) of type listUTI with invisibles and showing package contents without multiple selections allowed) as alias |
085 | on error |
086 | log "エラーしました" |
087 | return "エラーしました" |
088 | end try |
089 | |
090 | ################################### |
091 | #####パス処理 |
092 | ################################### |
093 | set strFilePath to (POSIX path of aliasFilePath) as text |
094 | set ocidFilePathstr to refMe's NSString's stringWithString:(strFilePath) |
095 | set ocidFilePath to ocidFilePathstr's stringByStandardizingPath() |
096 | set ocidFilePathURL to refMe's NSURL's alloc()'s initFileURLWithPath:(ocidFilePath) isDirectory:false |
097 | ####ファイル名を取得 |
098 | set ocidFileName to ocidFilePathURL's lastPathComponent() |
099 | ####拡張子を取得 |
100 | set ocidFileExtension to ocidFilePathURL's pathExtension() |
101 | ####ファイル名から拡張子を取っていわゆるベースファイル名を取得 |
102 | set ocidPrefixName to ocidFileName's stringByDeletingPathExtension |
103 | ####選んだファイルのディレクトリ |
104 | set ocidContainerDirURL to ocidFilePathURL's URLByDeletingLastPathComponent() |
105 | |
106 | ################################### |
107 | #####保存ダイアログ |
108 | ################################### |
109 | ###ファイル名 |
110 | set strPrefixName to ocidPrefixName as text |
111 | ###拡張子変える場合 |
112 | set strFileExtension to "PDF" |
113 | ###ダイアログに出すファイル名 |
114 | set strDefaultName to (strPrefixName & ".注釈入." & strFileExtension) as text |
115 | set strPromptText to "保存する名前を決めてください" |
116 | set strMesText to "保存する名前を決めてください" |
117 | ###選んだファイルの同階層をデフォルトの場合 |
118 | set aliasDefaultLocation to (ocidContainerDirURL's absoluteURL) as alias |
119 | ####ファイル名ダイアログ |
120 | ####実在しない『はず』なのでas «class furl»で |
121 | set aliasSaveFilePath to (choose file name strMesText default location aliasDefaultLocation default name strDefaultName with prompt strPromptText) as «class furl» |
122 | ####UNIXパス |
123 | set strSaveFilePath to POSIX path of aliasSaveFilePath as text |
124 | ####ドキュメントのパスをNSString |
125 | set ocidSaveFilePath to refMe's NSString's stringWithString:strSaveFilePath |
126 | ####ドキュメントのパスをNSURLに |
127 | set ocidSaveFilePathURL to refMe's NSURL's fileURLWithPath:ocidSaveFilePath |
128 | ###拡張子取得 |
129 | set strFileExtensionName to ocidSaveFilePathURL's pathExtension() as text |
130 | ###ダイアログで拡張子を取っちゃった時対策 |
131 | if strFileExtensionName is not strFileExtension then |
132 | set ocidSaveFilePathURL to ocidSaveFilePathURL's URLByAppendingPathExtension:strFileExtension |
133 | end if |
134 | |
135 | ################################### |
136 | ##NSDATAに読み込む |
137 | set ocidOption to (refMe's NSDataReadingMappedIfSafe) |
138 | set listResponse to refMe's NSData's alloc()'s initWithContentsOfURL:(ocidFilePathURL) options:(ocidOption) |error| :(reference) |
139 | if (item 2 of listResponse) = (missing value) then |
140 | log "正常処理" |
141 | set ocidReadData to (item 1 of listResponse) |
142 | else if (item 2 of listResponse) ≠ (missing value) then |
143 | set strErrorNO to (item 2 of listResponse)'s code() as text |
144 | set strErrorMes to (item 2 of listResponse)'s localizedDescription() as text |
145 | refMe's NSLog("■:" & strErrorNO & strErrorMes) |
146 | return "エラーしました" & strErrorNO & strErrorMes |
147 | end if |
148 | #PDF読み込み |
149 | set ocidTempPDFDoc to refMe's PDFDocument's alloc()'s initWithData:(ocidReadData) |
150 | set ocidReadData to (missing value) |
151 | ################################### |
152 | ##最適化されていないPDFで注釈が入れられない不具合に対応 |
153 | ##最適化していないと検索できない事があるので |
154 | ##テンポラリーとして最適化保存する |
155 | set ocidTempDirURL to appFileManager's temporaryDirectory() |
156 | set ocidUUID to refMe's NSUUID's alloc()'s init() |
157 | set ocidUUIDString to ocidUUID's UUIDString |
158 | set ocidSaveDirPathURL to ocidTempDirURL's URLByAppendingPathComponent:(ocidUUIDString) isDirectory:(true) |
159 | # |
160 | set ocidAttrDict to refMe's NSMutableDictionary's alloc()'s init() |
161 | ocidAttrDict's setValue:(511) forKey:(refMe's NSFilePosixPermissions) |
162 | set listDone to appFileManager's createDirectoryAtURL:(ocidSaveDirPathURL) withIntermediateDirectories:(true) attributes:(ocidAttrDict) |error| :(reference) |
163 | #パス |
164 | set ocidTmpPDFFilePathURL to ocidSaveDirPathURL's URLByAppendingPathComponent:("temp.pdf") isDirectory:(false) |
165 | #ちょいちょいクラッシュするので PDFDocumentOptimizeImagesForScreenOptionの使用は中止 |
166 | #set ocidOptionDict to refMe's NSMutableDictionary's alloc()'s init() |
167 | #ocidOptionDict's setValue:(true) forKey:(refMe's PDFDocumentOptimizeImagesForScreenOption) |
168 | #ocidOptionDict's setValue:(true) forKey:(refMe's PDFDocumentSaveTextFromOCROption) |
169 | #ocidOptionDict's setValue:(false) forKey:(refMe's PDFDocumentSaveImagesAsJPEGOption) |
170 | #set boolDone to ocidTempPDFDoc's writeToURL:(ocidTmpPDFFilePathURL) withOptions:(ocidOptionDict) |
171 | set boolDone to ocidTempPDFDoc's writeToURL:(ocidTmpPDFFilePathURL) |
172 | # |
173 | set ocidTempPDFDoc to (missing value) |
174 | delay 1 |
175 | ################################### |
176 | ##最適化保存したPDFで改めて処理開始 |
177 | #PDFドキュメント読み込み |
178 | #set ocidActivDoc to refMe's PDFDocument's alloc()'s initWithData:(ocidReadData) |
179 | set ocidActivDoc to refMe's PDFDocument's alloc()'s initWithURL:(ocidTmpPDFFilePathURL) |
180 | #【1】検索 |
181 | set ocidResultsArray to ocidActivDoc's findString:(strSearchString) withOptions:(refMe's NSCaseInsensitiveSearch) |
182 | ###################### |
183 | set ocidPropertiesDict to refMe's NSMutableDictionary's alloc()'s init() |
184 | #注釈をセットする |
185 | (ocidPropertiesDict's setValue:(strAnnotAuther) forKey:("/T")) |
186 | (ocidPropertiesDict's setValue:(strAnnotName) forKey:(refMe's PDFAnnotationKeyName)) |
187 | (ocidPropertiesDict's setValue:(28) forKey:(refMe's PDFAnnotationKeyFlags)) |
188 | (ocidPropertiesDict's setValue:(ocidSetColor) forKey:(refMe's PDFAnnotationKeyColor)) |
189 | (ocidPropertiesDict's setValue:(strAnnotContents) forKey:(refMe's PDFAnnotationKeyContents)) |
190 | (ocidPropertiesDict's setValue:(refMe's kPDFLineStyleNone) forKey:(refMe's PDFAnnotationKeyLineEndingStyles)) |
191 | # (ocidPropertiesDict's setValue:(ocidItemRect) forKey:(refMe's PDFAnnotationKeyRect)) |
192 | #注釈はハイライト |
193 | set ocidTyep to (refMe's PDFAnnotationSubtypeHighlight) |
194 | |
195 | #【1】検索結果を順番に処理 |
196 | repeat with itemArray in ocidResultsArray |
197 | #PDFPageを取得して |
198 | set ocidActivPage to itemArray's pages()'s firstObject() |
199 | #対象のRECTを取得 |
200 | set ocidItemRect to (itemArray's boundsForPage:(ocidActivPage)) |
201 | #結局検索結果のPDFPageで大丈夫だった |
202 | #set numPageNo to (ocidActivDoc's indexForPage:(ocidSelectPage)) |
203 | #set ocidActivPage to (ocidActivDoc's pageAtIndex:(numPageNo)) |
204 | #なぜか?Rectを再定義しないと注釈が生成されない事があるので |
205 | #面倒だけど再定義 |
206 | set listPoint to (item 1 of ocidItemRect) as list |
207 | set listSize to (item 2 of ocidItemRect) as list |
208 | set nunX to (item 1 of listPoint) as number |
209 | set numY to (item 2 of listPoint) as number |
210 | set numW to (item 1 of listSize) as number |
211 | set numH to (item 2 of listSize) as number |
212 | #RECT |
213 | set ocidSetRect to refMe's NSRect's NSMakeRect(nunX, numY, numW, numH) |
214 | #注釈を作成して対象ページに付与 |
215 | set ocidAddAnot to (refMe's PDFAnnotation's alloc()'s initWithBounds:(ocidSetRect) forType:(ocidTyep) withProperties:(ocidPropertiesDict)) |
216 | (ocidActivPage's addAnnotation:(ocidAddAnot)) |
217 | end repeat |
218 | |
219 | #処理が終わったら保存 |
220 | set boolDone to ocidActivDoc's writeToURL:(ocidSaveFilePathURL) |
221 | |
222 | |
223 | ######################## |
224 | ## クリップボードの中身取り出し |
225 | ######################## |
226 | on doGetPasteboard() |
227 | set appPasteboard to refMe's NSPasteboard's generalPasteboard() |
228 | set ocidPastBoardTypeArray to appPasteboard's types |
229 | ###テキストがあれば |
230 | set boolContain to ocidPastBoardTypeArray's containsObject:"public.utf8-plain-text" |
231 | if boolContain = true then |
232 | ###値を格納する |
233 | tell application "Finder" |
234 | set strReadString to (the clipboard as text) as text |
235 | end tell |
236 | ###Finderでエラーしたら |
237 | else |
238 | set boolContain to ocidPastBoardTypeArray's containsObject:"NSStringPboardType" |
239 | if boolContain = true then |
240 | set ocidReadString to ocidPasteboard's readObjectsForClasses:({refMe's NSString}) options:(missing value) |
241 | set strReadString to ocidReadString as text |
242 | else |
243 | log "テキストなし" |
244 | set strReadString to "入力してください" as text |
245 | end if |
246 | end if |
247 | return strReadString |
248 | end doGetPasteboard |
249 | |
250 | |
251 | ######################## |
252 | #AppIconのパスを求める |
253 | ######################## |
254 | on doGetAppIconAliasFilePath(argBundleID) |
255 | # |
256 | set appFileManager to refMe's NSFileManager's defaultManager() |
257 | set appSharedWorkspace to refMe's NSWorkspace's sharedWorkspace() |
258 | set ocidAppBundle to (refMe's NSBundle's bundleWithIdentifier:(argBundleID)) |
259 | if ocidAppBundle ≠ (missing value) then |
260 | set ocidAppPathURL to ocidAppBundle's bundleURL() |
261 | else if ocidAppBundle = (missing value) then |
262 | set ocidAppPathURL to (appSharedWorkspace's URLForApplicationWithBundleIdentifier:(argBundleID)) |
263 | end if |
264 | if ocidAppBundle ≠ (missing value) then |
265 | set ocidAppPathURL to ocidAppBundle's bundleURL() |
266 | else if ocidAppBundle = (missing value) then |
267 | set ocidAppPathURL to (appSharedWorkspace's URLForApplicationWithBundleIdentifier:(argBundleID)) |
268 | end if |
269 | if ocidAppPathURL = (missing value) then |
270 | tell application "Finder" |
271 | try |
272 | set aliasAppApth to (application file id strBundleID) as alias |
273 | on error |
274 | return "アプリケーションが見つかりませんでした" |
275 | end try |
276 | end tell |
277 | set strAppPath to POSIX path of aliasAppApth as text |
278 | set strAppPathStr to refMe's NSString's stringWithString:(strAppPath) |
279 | set strAppPath to strAppPathStr's stringByStandardizingPath() |
280 | set ocidAppPathURL to refMe's NSURL's alloc()'s initFileURLWithPath:(ocidFilePath) isDirectory:true |
281 | end if |
282 | ####ダイアログに指定アプリのアイコンを表示する |
283 | ###アイコン名をPLISTから取得 |
284 | set ocidPlistPathURL to ocidAppPathURL's URLByAppendingPathComponent:("Contents/Info.plist") isDirectory:false |
285 | set ocidPlistDict to refMe's NSMutableDictionary's alloc()'s initWithContentsOfURL:(ocidPlistPathURL) |
286 | set strIconFileName to (ocidPlistDict's valueForKey:("CFBundleIconFile")) as text |
287 | ###ICONのURLにして |
288 | set strPath to ("Contents/Resources/" & strIconFileName) as text |
289 | set ocidIconFilePathURL to ocidAppPathURL's URLByAppendingPathComponent:(strPath) isDirectory:false |
290 | ###拡張子の有無チェック |
291 | set strExtensionName to (ocidIconFilePathURL's pathExtension()) as text |
292 | if strExtensionName is "" then |
293 | set ocidIconFilePathURL to ocidIconFilePathURL's URLByAppendingPathExtension:"icns" |
294 | end if |
295 | ##-->これがアイコンパス |
296 | log ocidIconFilePathURL's absoluteString() as text |
297 | ###ICONファイルが実際にあるか?チェック |
298 | set boolExists to appFileManager's fileExistsAtPath:(ocidIconFilePathURL's |path|) |
299 | ###ICONがみつかない時用にデフォルトを用意する |
300 | if boolExists is false then |
301 | set aliasIconPath to POSIX file "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/AlertNoteIcon.icns" |
302 | else |
303 | set aliasIconPath to ocidIconFilePathURL's absoluteURL() as alias |
304 | end if |
305 | return aliasIconPath |
306 | end doGetAppIconAliasFilePath |
307 | |
308 | |
AppleScriptで生成しました |
| 固定リンク