Cocoa AppleScript PDFからRTF完全版 (ワード検索し、背景色を変更) AppleScript [10]

AppleScript[10](CatchImage)

AppleScript [10] Cocoa AppleScript 第3版 PDFからRTF完全版 (ワード検索し、背景色を変更)
 "Skim"アプリを利用して「文字色やフォント等の属性情報付き RTF(RichTextFormat) データ:raw RTFデータ」を取得する方法を教えて頂いたので、PDFオリジナルの属性情報付き Styled String にて RTFファイル書き出し!( 前回から引き続き、TXTファイル書き出しに問題はありません )
 申し訳ありません。 PDFオリジナルのテキスト属性情報が取得できない問題は、"Skim"アプリのせいではなく やはり筆者の認識不足でした。
  ① PDFオリジナルのテキスト属性情報を RTFファイル初期値としてセット 
  ② 追加(変更)サンプルとして、指定キーワードで検索し文字背景色を黄色に変更(全箇所) 

 (注) AppleScript にて、フォルダ選択ダイアログを利用します!

 2021/11/03  Ver. 3.5「Cocoa AppleScript 第3版」PDFファイルから、オリジナルの「文字色やフォント等の属性情報付き」RTFデータの抽出に成功 with "Skim"アプリ
→ AppleScript は "filePath.scpt" ファイルの「前回のハンドラーを修正(置き換え)」、今回 VBAコードに変更や追加はありません。


 念のため書いておきますが、PDF内の文字が画像の一部になったままではテキスト抽出できないため その場合はいわゆる「OCR(光学文字認識)」スキャンを行う必要あり!

 【注意】テキストファイルの上書き(置き換え)を行う場合、必ず該当ファイルを閉じてから実行して下さい!!
 テキストエディタ等で閉じるのを忘れた場合(つまり、ファイルをオープンしたままだと)、メモリ不足など Mac が深刻な症状に陥る場合があります。 筆者もテストの際2、3度「やっちまった」次第で、いきなり Safari や Excelが終了してビックリ...

 「ぴよまるソフトウェア」の長野谷さん から、ちょっとチートなやり方を教えて頂きました! raw RTFデータ取得までは「用語説明(dictionary)」を読めば気付くはずと思いますが、その後の処理は... RTFデータフォーマット、恐るべしって感じです。
 ちなみに オリジナルコードを書いたのは、  Script Debugger  を開発している Late Night Software Ltd. の Shane Stanley さんだそうです。
 長野谷さんの以下ブログは AppleScriptの最新情報を入手可能なブログ(ただし、中級者以上向け)で、超オススメ!

 以下が「用語説明(dictionary)」のサンプルで、"Skim.app" などのアプリケーション・アイコンを [アプリケーション]-[ユーティリティ] 内の スクリプトエディタ.app のアイコン上にドラッグ&ドロップすると表示されます!

AppleScript[10] Png02





 【AppleScriptの修正】 AppleScript [10] Cocoa AppleScript 第3版 PDFからRTF完全版 (ワード検索し、背景色を変更) 

 まず、Excel メニューバーの [ヘルプ] - [更新プログラムのチェック] にて、適用されていないアップデートがあれば行ってください。


 VBA の AppleScriptTask コマンド パラメータの注意点 

  ファイルパスと区別するため フォルダパス指定には 末尾に必ず / を付加 してください! フォルダフルパス なら 先頭と末尾が必ず / となります。
 OneDriveiCloudDropboxBox 等のサービスをブラウザ利用でなくフォルダにリンクしている場合も(リンク)パスが判れば指定可能ですが、https:// が先頭に付いたり ネットワーク経由のアクセスのためとんでも無く時間がかかりますので ローカルPC(Mac本体内の高速なSSDやHDDドライブ)上のフォルダパスを指定してください。


 第3版 Cocoa AppleScript コード 前回追加したハンドラーを修正 

 RTFファイル書き出し時のみ有効な「検索キーワード」を先頭パラメータとして追加したため、合計4パラメータに! なお、TXTファイル書き出し時 「ワード検索のキーワード」は無効ななため、空文字列 "" をセットすると良いでしょう。 もちろん、RTF出力で「ワード検索」が必定ない場合も!

 2021/11/03  Ver. 3.5「Cocoa AppleScript 第3版」PDFファイルから、オリジナルの「文字色やフォント等の属性情報付き」RTFデータの抽出に成功 with "Skim"アプリ
→ AppleScript は "filePath.scpt" ファイルの「前回のハンドラーを修正(置き換え)」、今回 VBAコードに変更や追加はありません。


 以下 末尾のハンドラーを 順に 置き換え後 、コンパイル後に ファイルを保存 してください。 操作方法がよく解らなくても、  前回  以前の記事を読めば大丈夫です。

 ちなみに、全 AppleScript コードのダウンロードは  こちらから! 
上記リンクを右クリックして「リンク先のファイルをダウンロード」等を選択してダウンロード後 ダブルクリックして任意のテキストエディタで開き、 [command]+[A] で全選択し [command]+[C] でコピー後、スクリプトエディタ内で [command]+[V] にて貼り付けしてください。 ( "Google Chrome" ブラウザの場合、上記リンクを右クリックして「名前を付けてリンク先を保存」を選択してダウンロード後... )
 (注) [ Unicode(UTF-8) 、改行コードは LF ] ファイル置き場として、筆者の旧ブログを利用

 スクリプトエディタ.app の操作方法や filePath.scpt の保存フォルダ が分からない方は
 こちら  をお読みください。






--2021/10/20 Ver.3.3 Cocoa AppleScript 対応 第3版 以下ハンドラーを追加
--2021/10/30 Ver.3.4 作成されるRTFファイルに不備があったため修正  (+「文字の色・サイズ・フォント等の属性」を初期セットし、検索キーワードの色を全箇所変更)
--2021/11/03 Ver.3.5 PDFファイルから、オリジナルの「文字色やフォント等の属性情報付き」RTFデータの抽出に成功 with "Skim"アプリ
-- 指定フォルダ(子フォルダを含む)内のPDFファイルを順に読み込み、テキストファイルを書き出し
-- パラメータ[1]  検索キーワード(rtf指定時のみ有効で、全箇所「黄」に変更)txt時は無視
-- パラメータ[2]  プロンプト文字列:""なら、当ハンドラー設定の初期値
-- パラメータ[3]  初期表示フォルダ:""なら、無指定(前回と同じフォルダを開く)
-- パラメータ[4]  書式": txt" or "rtf"(省略時は、"txt":PlainText指定)RTF:RichTextFormat
-- 実行結果[0~n] (発見した)PDFファイルのフルパス、ただし ".pdf" の拡張子は削除済み
--[注意] Macに予め、Skimアプリ(無料のPDFリーダー+注釈付加ツール)のインストールが必要!
on putTextFromPdfOfSelectFolder(paramStr)
  set returnText to ""
  set promptStr to "PDF格納フォルダを選択!(子フォルダ対応)" --  ファイル選択時のプロンプト文字列
  
  try
    set tmp to (AppleScript's text item delimiters) --  現在のデリミタを保存
    set (AppleScript's text item delimiters) to {LF} -- デリミタを変更
    set paramList to (every text item of paramStr) -- 分割し、List格納
    set (AppleScript's text item delimiters) to tmp --  保存したデリミタに戻す
    
    set searchWord to ((first item of paramList) as string) --検索キーワード(RTFのみ有効)
    set paramList to (rest of paramList) --最初の要素を削除
    set str to ((first item of paramList) as string)
    if (str ≠ "") then --not=は「/=」と記述
      set promptStr to str
    end if
    set paramList to (rest of paramList) --最初の要素を削除
    set defaultLocation to ((first item of paramList) as string)
    set paramList to (rest of paramList) --最初の要素を削除
    
    if (count paramList) = 0 then
      set isRtf to false
    else
      set rtf to ((first item of paramList) as string)
      if rtf is in {"rtf", "RTF", "Rtf"} then
        set isRtf to true --RTF:RichTextFormat
      else
        set isRtf to false
      end if
    end if
    
    activate --ウィンドウの前面に表示!
    if (defaultLocation = "") then
      set theAlias to (choose folder with prompt promptStr)
    else
      set defaultLocation to (POSIX path of defaultLocation)
      set theAlias to (choose folder with prompt promptStr default location defaultLocation)
    end if --選択したフォルダの「エイリアス値」が返される
    
    --tell application "Finder"
    set theFolder to (POSIX path of (theAlias as string)) -- 指定フォルダのPOSIXパス
    --end tell
    
    set fileWriteCount to 0 --ファイル書き込み成功 件数
    set theList to {}
    set theList to my retFullPathWithinAFolderWithRecursiveFilterByExt(theFolder, "pdf")
    
    tell application "Skim" --AppleScriptで利用し易い PDF読み込み(注釈付加も可能)アプリ
      activate --"Skim"App
      
      repeat with fName in theList --PDFファイルのフルパス(ただし、末尾の .pdf は削除)
        
        set theDoc to (open (fName & ".pdf")) --Open PDF's file
        
        tell front document --該当PDFファイルのみを対象!(同時に複数Open可能なため)
          if isRtf then --RTF:RichTextFormat
            set rtfFromPDF to (get text for as rich text) --該当PDFから、全[default:RTF]を抽出 (属性なしRTF)
            set rawRtfData to RTF of rtfFromPDF --該当PDFから、全[default:RTF]を抽出 (raw RTF Data)
          else
            set textFromPDF to (get text for as text) --該当PDFから、全テキストを抽出
          end if
        end tell --「文字コードと改行コード」は元のPDFファイルのまま、抽出
        
        --[注1] 既に同一ファイルが存在したら、無条件 置き換え
        --[注2] テキストファイル(文字コードUTF-8)の改行コードは、PDFファイルのまま
        if isRtf then --RTF:RichTextFormat
          set theResult to my saveStyledTextAsRTF(rtfFromPDF, rawRtfData, (fName & ".rtf"), searchWord) --RTFのみ、検索文字列の色を全箇所変更
        else
          set theResult to my write_to_text_file_asUTF8(textFromPDF, (fName & ".txt"), false, LF)
        end if
        if theResult then --ファイル書き込み成功の場合
          set fileWriteCount to (fileWriteCount + 1)
        end if
        
        close theDoc --Close PDF's file
        
      end repeat
      
      delay 3.0 -- 無くても、ほとんどの場合 動作するはず
      quit --"Skim"Appの終了
    end tell
    
    activate
    --display dialog (fileWriteCount as string) & " 件のテキストファイルを書き込みました!" buttons {"10秒で閉じます!"} with icon caution giving up after 10
    display alert (fileWriteCount as string) & " 件のテキストファイルを書き込みました!" as informational buttons {"了解"}
    
    set returnText to "" --  ハンドラ-の戻り値を初期化
    set returnText to getTextWithDelimiters(theList, {LF}) --ハンドラ-の戻り値へ 格納
    set the clipboard to {} --クリップボードの初期化
    set the clipboard to returnText --読み込みファイルデータを、クリップボードへ格納(UTF-8)
    
    return returnText
    
  on error
    set returnText to "" --  ハンドラ-の戻り値を初期化
    set (AppleScript's text item delimiters) to tmp --  保存したデリミタに戻す
    display dialog "★ AppleScriptTask (putTextFromPdfOfSelectFolder) ★" & return & return & "   キャンセル あるいは 異常終了" buttons {"10秒で閉じます!"} with icon caution giving up after 10
  end try -- 「キャンセル」ボタン押下時用のエラーハンドリング
  
  return returnText -- display dialog returnText
  
end putTextFromPdfOfSelectFolder




-- Original Code Created by: Shane Stanley
-- Original Code Created on: 2019/09/17
-- [注]Shane Stanley さんは Script Debugger を開発している Late Night Software Ltd. の方。
--スタイル付きテキストを、指定フルパス(POSIX path)に  RTF で書き出し
--[1] RTF属性サンプルとして、テキスト全体に「文字色・フォント+文字サイズ」を初期設定
--[2] 指定キーワードで検索し、黄色に変更(全箇所)
on saveStyledTextAsRTF(rtfFromPDF, rawRtfData, theFilePath, searchWord)
  try
    activate
    
    (*
    --(注) フォント(+フォントサイズ)は PostScript名で指定 Sample:Osaka-等幅18ポ
    --set theFont to NSFont's fontWithName:"Meiryo" |size|:18 --メイリオ18ポ
    set theFont to NSFont's fontWithName:"Osaka-Mono" |size|:18
    set theCyanColor to NSColor's cyanColor() --Sample:文字色をシアン設定
    set theDict to NSDictionary's dictionaryWithObjects:{theCyanColor, theFont} forKeys:{NSForegroundColorAttributeName, NSFontAttributeName}
    set theATS to NSMutableAttributedString's alloc()'s initWithString:rtfFromPDF attributes:theDict --RTF属性の初期設定
    *)
    
    --[rawRtfData] raw RTF data(オリジナルの色やフォント等の属性情報付きRTF data)
    set theData to (NSArray's arrayWithObject:rawRtfData)'s firstObject()'s |data|()
    set theATS to NSMutableAttributedString's alloc()'s initWithRTF:theData documentAttributes:(missing value) --raw RTF data(オリジナルの色・フォント等)
    
    --指定キーワードで検索し、黄色に変更(全箇所)--RTF属性の追加
    --2021/11/03 ワード検索用に rawRtfData を使用すると、エラー → rtfFromPDF
    if searchWord ≠ "" then
      set theYellowColor to NSColor's yellowColor()
      my changeColorOfSearchWord(theATS, rtfFromPDF, searchWord, theYellowColor)
    end if
    --時間はかかるかもしれないが、別キーワードで検索を繰り返すことも可能!
    --set theRedColor to NSColor's redColor()
    --my changeColorOfSearchWord(theATS, rtfFromPDF, "AppleScript", theRedColor)
    
    --set theATSsLength to theATS's |string|()'s |length|() -- 's string's Length
    set theATSsLength to theATS's |length|() --NSMutableAttributedString's Length
    set allRange to current application's NSMakeRange(0, theATSsLength)
    
    --  write the attributed string out as an RTF file(無条件、置換)
    --PDFファイルの「文字(改行)コード」のまま、テキストファイル書き込み!
    set rtfData to theATS's RTFFromRange:allRange documentAttributes:{DocumentType:NSRTFTextDocumentType} --UTI (public.rtf) 属性を設定
    
    return (rtfData's writeToFile:theFilePath atomically:true) as boolean --UTF-8(LF)想定
    
  on error
    display dialog "★ AppleScriptTask (saveStyledTextAsRTF) ★" & return & return & "   キャンセル あるいは 異常終了" buttons {"10秒で閉じます!"} with icon caution giving up after 10
    return false
  end try -- 「キャンセル」ボタン押下時用のエラーハンドリング
  
end saveStyledTextAsRTF




-- Original Code Created 2017-09-19 by Takaaki Naganoya
-- Original Code 2017 Piyomaru Software
--指定のAttributedString内で指定文字列が含まれる箇所に指定の色をつける(結果は参照渡し)
on changeColorOfSearchWord(mutableAttrStr, origStr, aTargStr, aColor)
  try
    set rangeArray to my searchWordWithRange(origStr, aTargStr)
    repeat with aRange in rangeArray
      --(mutableAttrStr's addAttribute:(NSForegroundColorAttributeName) value:aColor range:aRange) --文字色を aColor に変更
      (mutableAttrStr's addAttribute:(NSBackgroundColorAttributeName) value:aColor range:aRange) --背景色を aColor に変更
    end repeat
    
  on error --Add by Ataruchi 2021/10/30
    display dialog "★ AppleScriptTask (changeColorOfSearchWord) ★" & return & return & "   キャンセル あるいは 異常終了" buttons {"30秒で閉じます!"} with icon caution giving up after 30
  end try
end changeColorOfSearchWord




-- Original Code Created 2017-09-19 by Takaaki Naganoya
-- Original Code 2017 Piyomaru Software
--指定テキストデータ(aTargText)内に、指定文字列(aSearchStr)が含まれる範囲情報(NSRange)をすべて取得する
on searchWordWithRange(aTargText, aSearchStr)
  try
    set aStr to NSString's stringWithString:aTargText
    set bStr to NSString's stringWithString:aSearchStr
    set hitArray to NSMutableArray's alloc()'s init()
    set cNum to (aStr's |length|()) as integer
    
    set aRange to current application's NSMakeRange(0, cNum)
    
    repeat
      set detectedRange to aStr's rangeOfString:bStr options:NSLiteralSearch range:aRange
      set aLoc to (detectedRange's location)
      if (detectedRange's |length|() = 0) then exit repeat --Add by Ataruchi 2021/10/30
      --CAUTION !!!! Sometimes aLoc returns not NSNotFound (-1) but a Very large number
      if (aLoc > 9.999999999E+9) or (aLoc = (current application's NSNotFound)) then exit repeat
      
      hitArray's addObject:detectedRange
      
      set aNum to aLoc as integer
      set bNum to (detectedRange's |length|) as integer
      
      set aRange to current application's NSMakeRange(aNum + bNum, cNum - (aNum + bNum))
    end repeat
    
    return hitArray
    
  on error --Add by Ataruchi 2021/10/30
    display dialog "★ AppleScriptTask (searchWordWithRange) ★" & return & return & "   キャンセル あるいは 異常終了" buttons {"30秒で閉じます!"} with icon caution giving up after 30
    hitArray's removeAllObjects() --要素を全て削除する
    set emptyArray to NSMutableArray's alloc()'s init() --return値を(再)初期化
    return emptyArray
  end try
end searchWordWithRange

 Cocoa用の(クラス)オブジェクト定義が足りなくて、このままでは コンパイルエラーになります。
 AppleScript 先頭 部分の property定義(propertyで始まる行すべて)を 以下で置き換えてください! 



--NSObjectを最上位とする以下NSオブジェクトは Cocoa 用のオブジェクトで、Objective-C で実装されている!
property |NSURL| : a reference to current application's |NSURL| --SubDir内を除外したDir内の列挙時に利用
property NSFont : a reference to current application's NSFont
property NSArray : a reference to current application's NSArray
property NSColor : a reference to current application's NSColor
property NSString : a reference to current application's NSString --dirPath, fileName, ext 取得可
property NSPredicate : a reference to current application's NSPredicate --正規表現 Esc処理に一部問題あり
property NSDictionary : a reference to current application's NSDictionary
property NSEnumerator : a reference to current application's NSEnumerator --列挙用
property NSFileManager : a reference to current application's NSFileManager --"Finder" の代替Obj
property NSLiteralSearch : a reference to current application's NSLiteralSearch
property NSMutableArray : a reference to current application's NSMutableArray --変更可能な NSArray
property NSMutableString : a reference to current application's NSMutableString --変更可能な NSString
property NSUTF8StringEncoding : a reference to current application's NSUTF8StringEncoding --UTF-8Encode
property NSFontAttributeName : a reference to current application's NSFontAttributeName --フォント
property NSAttributedString : a reference to current application's NSAttributedString
property NSMutableAttributedString : a reference to current application's NSMutableAttributedString
property NSForegroundColorAttributeName : a reference to current application's NSForegroundColorAttributeName --Styled String 文字色
property NSBackgroundColorAttributeName : a reference to current application's NSBackgroundColorAttributeName --Styled String 背景色
property NSRTFTextDocumentType : a reference to current application's NSRTFTextDocumentType
property NSDocumentTypeDocumentAttribute : a reference to current application's NSDocumentTypeDocumentAttribute
property NSDirectoryEnumerationSkipsSubdirectoryDescendants : a reference to current application's NSDirectoryEnumerationSkipsSubdirectoryDescendants --Skip SubDir's (File or Dir)
property NSDirectoryEnumerationSkipsPackageDescendants : a reference to current application's NSDirectoryEnumerationSkipsPackageDescendants --Skip Package. ex) "Microsoft Excel.app"
property NSDirectoryEnumerationSkipsHiddenFiles : a reference to current application's NSDirectoryEnumerationSkipsHiddenFiles --Skip HiddenFiles for Enumeration

-- (global) 定数の宣言
property HT : ASCII character (9) --水平タブ(タブ区切りテキストファイルのタブコード) = tab
property LF : ASCII character (10) -- vbLf [macOS10~ を含むUnix系の改行コード] for Unix
property CR : ASCII character (13) -- vbCr [~Macintosh System9 の改行コード] for (OLD Mac)
property CRLF : CR & LF -- vbCrLf [MS Windows系の改行コード] for Win10, Win7
--  Excel対応のクリップボードに 区切り文字 vbCrLf を利用する理由
--  Excelでは「セル内の改行コードとしてvbLf」が用いられているため、
--  「改行コードとしてvbCrLf」を挟まないと [command]+[V]失敗!
property HIDDEN_FILES : true --「隠しファイル&フォルダ」無効(除外する) false 有効(除外しない)


 ちなみに、  ret  で始まる AppleScript の ハンドラー (VBAのプロシージャ相当の呼び出し単位)は Cocoa AS で主処理が実装されていますので、カスタマイズは慎重にお願いします。 その他の ハンドラー も Cocoa AS 実装の部分が判るように記述 しています。("NS"で始まるクラスは Cocoaのオブジェクトで、それ以外で何も記述が無ければ、Vannila AS ということ) Vanilla AS 部分はカスタマイズが楽で「 AppleScriptTask コマンド経由の呼び出し」ではなく、「 filePath.scpt をダブルクリック後に起動される スクリプトエディタ.app にて実行」すれば( Vanilla AS 部分の場合 )エラー発生箇所が判ります。 先頭部分の on test() から end test 内にサンプルのデバッグ用コードを記述済みのため、変更後に [command]+[K] でコンパイル、 test() の実行は [command]+[R] で可能です。 動作に問題が無い場合は [command]+[S] にて保存を忘れないように!

 VBA だけでなく AppleScript コードも テキスト保存が可能なため、変更前に [command]+[A] にて全選択後 [command]+[C] でコピー してテキストエディタ等に [command]+[V] にてペースト(貼り付け)しておけば元に戻せます。 カスタマイズ作業前に filePath.scptAppleScriptTaskコマンドを記述したExcelファイル を ローカルPC上か クラウド領域にバックアップしておくと なお良いでしょう。


AppleScript[10] Png01

 【VBA】 AppleScript [10] Cocoa AppleScript 第3版 PDFからRTF完全版 (ワード検索し、背景色を変更) 

 今回、VBA インターフェース部分の 追加および変更はありません! 

 全 Excel VBAコードのダウンロードは  こちらから! 
上記リンクを右クリックして「リンク先のファイルをダウンロード」等を選択してダウンロード後 ダブルクリックして任意のテキストエディタで開き、 [command]+[A] で全選択し [command]+[C] でコピー後、VBEの( 通常 Module1 )のコードウィンドウ内で [command]+[V] にて貼り付けしてください。 ( "Google Chrome" ブラウザの場合、上記リンクを右クリックして「名前を付けてリンク先を保存」を選択してダウンロード後... )
 (注) [ Unicode(UTF-8) 、改行コードは LF ] ファイル置き場として、筆者の旧ブログを利用

 RTFファイル書き出し時のみ有効な「検索キーワード」を先頭パラメータとして追加したため、合計4パラメータに! なお、TXTファイル書き出し時 「検索キーワード」は無効ななため、空文字列 "" をセットすると良いでしょう。 もちろん、RTF出力で「ワード検索」が必定ない場合も!

 パラメータ[4] 省略時も "txt" 指定! となります。

(1) 「 イミディエイト ウィンドウ から call WriteTextFileFromPdfOfFolder() 」等で実行すると まず フォルダ選択ダイアログ が開くため、PDFファイルを格納したフォルダを指定!
(2) 子フォルダ対応で、「 拡張子 pdf 」を持つファイルのフルパス(処理し易いよう、末尾の .pdf は削除)のリストを作成
(3) 「Skimアプリ」で (2) のリストを順に処理。 PDFファイルをオープン後 各PDF内のテキストを抽出し、(2) のパスの末尾に .txt あるいは .rtf を付加して 同一フォルダ内に テキストファイルとして書き込み。 (同一ファイル名が存在した場合、無条件 ファイルを置き換え)
(4) 正常終了すると、ファイル書き込み件数をダイアログ表示(処理結果が返らないため、 閉じる までずっと表示するよう変更)

 処理結果として、結果文字列クリップボード に (2) のリスト(配列)をセット!

 rtf を指定して RTF (RichTextFormat) ファイルを書き出す場合、 PlainText に次のようなテキスト属性情報を付加することが可能。
 ① PDFオリジナルのテキスト属性情報を RTFファイル初期値 としてセット 
 ② 追加(変更)サンプルとして、指定キーワードで検索し 文字背景色 を黄色に変更(全箇所) 



 PDFファイルから テキスト出力(PlainText あるいは RTF)機能に関しては これで心残りが無くなったため、PDF編はこれで最後となります。
 "Skim" は無料だけど、AppleScriptフル対応で ホント素晴らしい! リーダー機能に加え、注釈も付加することが出来るし...

 今まで作成した AppleScript 部品を組み合わせて、「PDFからテキスト抽出」機能を付加しました! 部品の再利用化が進むと AppleScript および VBA の両方で少ないコードで機能付加が可能となるため、 再利用し易いように部品を設計するのも重要です。 この辺りは経験を重ねるしかないと思いますので、 VBA や AppleScript に限らず プログラムコードをたくさん書けば 誰でもできるようになるはず...

 Mac の VBA のみで実現出来ないことをまた見つけたら、 AppleScript で補完したいと思います! macOS12以降で追加される「ショートカット」アプリとの連携方法も理解できたら、記事にまとめないと...

 早く macOS12 が安定すると良いですね。(筆者は、それまで macOS11.6.1 を使用) 愛用の Mac mini 2014 でも遅くなりませんように! macOS11 では intelチップ以外のMacで AppleScript が低速なコアのみで実行されるというバグ? があったため、 macOS12 の AppleScript 実行速度にビックリするそうですよ! intelチップのMacでも少々速くなるらしいです。




 [command] + [Q] にてまず VBE を終了し、Excel のウィンドウ内を選択して [command] + [Q] にて Excel も終了させます。 「作業中のブック」を保存するか確認のダイアログ画面が表示された場合は 「保存」しましょう。 「自動保存」済みの場合、保存するかどうかの確認ダイアログ画面は表示されません。


 AppleScriptTask コマンドの結果文字列(エラーがあれば、空文字 "" を返す)だけでなく、クリップボードにも同じ内容(改行コードは異なる場合あり)をセットしているため、必要があれば「片方のみ」に変更してください。 ただし、「フルパスやファイル名以外」を返す結果文字列の場合 クリップボードにはセットしないため、「イミディエイト ウィンドウ」にて確認してください!
 AppleScript から VBA に数百ファイル以上結果が返されるのであれば、大量データが渡されるオーバーヘッドも含め、クリップボードのみの利用(結果文字列は、正常終了/異常終了のみ判れば良い)がオススメです。 また、バックグラウンド処理前提の場合は 相互で クリップボードの中身を消してしまう可能性 があるため、結果文字列のみの利用が良いでしょう。

 1日2時間くらい2ヶ月 AppleScript を勉強した成果として、今回の記事を書きました。 Cocoa AppleScript に関しては初心者のため、不具合があればコメント等で教えて頂けると嬉しいです。








Macブログ ランキング アイコン
最後まで読んでいただき、ありがとうございます。 また、お越しくださいませ。
// アタル
For follow LINE Reader Group!Subscribe to this blog on Feedly!

Next Post Previous Post
3 Comments
  • アタル
    アタル 2021年11月4日 20:04

    --「スクリプトエディタ.app」にて以下のAppleScriptを実行すると、指定PDFファイルを RTFファイルに変換します!(PDFのテキスト属性のまま)
    --予め、"Skim.app" インストール要

    ------------------------------------------------------------
    --Copyright 2021- ataruchi. [ https://twitter.com/ataruchi ]
    use AppleScript version "2.4"
    use scripting additions
    use framework "Foundation"
    use framework "AppKit"

    tell application "Skim"

    activate --"Skim.app" を最前面で表示

    --オープンしたPDFファイルのフルパスをセット
    set pdfFile to (open (POSIX path of (choose file of type {"com.adobe.pdf"})))

    tell front document --pdfFile

    set rawRtfData to RTF of (get text for as rich text) --raw RTF dataの取得

    set rtfData to (current application's NSArray's arrayWithObject:rawRtfData)'s firstObject()'s |data|() --パイプで囲み、AppleScript予約語と区別

    --Styled String 属性を取得
    set theATS to (current application's NSAttributedString's alloc()'s initWithRTF:rtfData documentAttributes:(missing value)) --PDFオリジナルのテキスト属性のまま

    close pdfFile

    end tell

    quit --"Skim.app" を終了

    end tell

    activate --「Save File」ダイアログを最前面で表示
    set rtfFile to POSIX path of (choose file name default name "test.rtf") --出力RTFファイルパス

    --set theATSsLength to theATS's |string|()'s |length|() -- 's |string|'s Length
    set theATSsLength to theATS's |length|() --NSAttributedString's Length
    set allRange to current application's NSMakeRange(0, theATSsLength) --テキスト全体

    -- write the attributed string out as an RTF file(無条件、置換)
    --PDFファイルの「文字(改行)コード」のまま、テキストファイル書き込み!
    set atsData to theATS's RTFFromRange:allRange documentAttributes:{DocumentType:current application's NSRTFTextDocumentType} --UTI (public.rtf) 属性を設定

    --「結果」テキストファイル出力に成功したら true 、失敗なら false が返る
    return (atsData's writeToFile:rtfFile atomically:true) as boolean --UTF-8(LF)想定
    ------------------------------------------------------------

  • アタル
    アタル 2021年11月4日 20:19

    --「スクリプトエディタ.app」にて以下のAppleScriptを実行すると、PDFファイル内の一部を範囲選択後、指定範囲部分を RTFファイルに変換します!(PDFのテキスト属性のまま)
    -- 予め"Skim"を起動後に任意のPDFファイルをオープンして、任意の領域の範囲「選択:selection」が必要!

    ------------------------------------------------------------
    -- Created by: Shane Stanley
    -- Created on: 2019/09/17
    -- [注]Shane Stanley さんは Script Debugger を開発している Late Night Software Ltd. の方。

    use AppleScript version "2.4"
    use scripting additions
    use framework "Foundation"
    use framework "AppKit"

    set fullAttString to current application's NSMutableAttributedString's new()

    tell application "Skim"
    tell front document
    set aSel to selection

    repeat with i in aSel
    set theDatas to RTF of i

    repeat with aData in theDatas
    set theData to (current application's NSArray's arrayWithObject:aData)'s firstObject()'s |data|()
    set theAttString to (current application's NSAttributedString's alloc()'s initWithRTF:theData documentAttributes:(missing value))
    (fullAttString's appendAttributedString:theAttString)
    end repeat

    end repeat

    end tell
    end tell

    --return fullAttString
    --これ以降は、 Ataruchi が追加
    --取得した NSMutableAttributedString Object(fullAttString) を RTFファイルに書き出し
    activate
    set rtfFile to POSIX path of (choose file name default name "selection.rtf")

    --set theATSsLength to fullAttString's |string|()'s |length|() -- 's string's Length
    set theATSsLength to fullAttString's |length|() --NSAttributedString's Length
    set allRange to current application's NSMakeRange(0, theATSsLength)

    -- write the attributed string out as an RTF file(無条件、置換)
    --PDFファイルの「文字(改行)コード」のまま、テキストファイル書き込み!
    set atsData to fullAttString's RTFFromRange:allRange documentAttributes:{DocumentType:current application's NSRTFTextDocumentType} --UTI (public.rtf) 属性を設定

    return (atsData's writeToFile:rtfFile atomically:true) as boolean --UTF-8(LF)想定
    ------------------------------------------------------------

  • アタル
    アタル 2021年11月4日 20:28

    --「スクリプトエディタ.app」にて以下のAppleScriptを実行すると、PDFファイル内の一部を範囲選択後、指定範囲部分を PlainTextとして取得し、クリップボードにセット!
    -- 予め"Skim"を起動後に任意のPDFファイルをオープンして、任意の領域の範囲「選択:selection」が必要!

    ------------------------------------------------------------
    -- Original code Created by: Shane Stanley
    -- Original code Created on: 2019/09/17
    -- http://piyocast.com/as/archives/7387 より転載 ( AppleScriptの穴 by ぴよまるソフトウェア )
    -- [注]Shane Stanley さんは Script Debugger を開発している Late Night Software Ltd. の方。

    set theText to ""
    tell application "Skim"
    tell front document
    set aSel to selection
    repeat with anItem in aSel
    set theText to theText & (characters of anItem) as text
    end repeat
    end tell
    end tell

    --return theText
    --これ以降は、 Ataruchi が追加
    --クリップボードに、結果テキストをセット
    set the clipboard to theText
    ------------------------------------------------------------

Add Comment
comment url