Archive for the 'Skim' Category

2017/06/09 指定PDFの最初のページからアノテーションを削除する

指定PDFの最初のページに添付されたアノテーション(Preview.app上ではマークアップと呼ばれる)を削除するAppleScriptです。

■実行前(Before)
pdf_annotation1_resized.png

■実行後(After)
pdf_annotation2_resized.png

とりあえず、指定PDFの指定ページ上のアノテーションを取得して削除できるようになりました。このあたり、もはやプログラミングではなく単なる調査です(汗)。

アノテーションを検出するScriptにも記載してあるとおり、Skimで添付したアノテーションは処理できません。Preview.appで添付したアノテーションを処理対象にしています。Preview.appで添付したアノテーションはSkimでもAdobe Acrobatでも表示が可能です。

AppleScript名:指定PDFの最初のページからアノテーションを削除する
– Created 2017-06-09 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “Quartz”
–http://piyocast.com/as/archives/4681

set aHFSPath to (choose file of type {“com.adobe.pdf”} with prompt “Choose a PDF with Annotation”)
set aPOSIX to POSIX path of aHFSPath
set aURL to (current application’s |NSURL|’s fileURLWithPath:aPOSIX)

set aPDFdoc to current application’s PDFDocument’s alloc()’s initWithURL:aURL
set pCount to aPDFdoc’s pageCount()

set firstPage to (aPDFdoc’s pageAtIndex:0)

set anoList to (firstPage’s annotations()) as list

repeat with i in anoList
  (firstPage’s removeAnnotation:i)
end repeat

aPDFdoc’s writeToFile:aPOSIX

★Click Here to Open This Script 

2017/06/08 指定PDFの最初のページからアノテーションを取得する

指定PDFの最初のページに添付されたアノテーション(Preview.app上ではマークアップと呼ばれる)を取得するAppleScriptです。

pdf_annotation1_resized.png

とりあえず、指定PDFの指定ページ上のアノテーションを取得して種類や大きさを取得できるようになりました。

日常的に利用しているPDFビューワーとしてはオープンソースのSkimがあり、むしろPreview.appよりもこちらの方を主に利用していますが、Skimで添付したアノテーションについては保存形式が異なる(外部保存?)ようで、本Scriptでは検知できませんでした。テストにはPreview.app上で編集して任意のアノテーション(マークアップ)を追加したPDFを用意する必要があります。

PDF上の指定ページ上のアノテーションを取得することはできるようになりましたが、取得することが目的ではなく、Script側からアノテーションを作成してPDFに添付することが最終目的です。アノテーションの作成についてはあまり情報が見つからず、ちょっと苦労させられています。

他のアプリケーションに依存しないでPDFの各種処理が行えることが望ましく(とくに、Adobe Acrobatが入っていない環境でも処理できることが望ましい)、アノテーションの添付はAppleScriptでCocoaの機能を利用して行うPDF処理としては「最後の難関」として残っています。ほかはひととおり他のアプリケーションなしでできています。

AppleScript名:指定PDFの最初のページからアノテーションを取得する
– Created 2017-06-08 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “Quartz”
–http://piyocast.com/as/archives/4679

set aHFSPath to (choose file of type {“com.adobe.pdf”} with prompt “Choose a PDF with Annotation”)
set aPOSIX to POSIX path of aHFSPath
set aURL to (current application’s |NSURL|’s fileURLWithPath:aPOSIX)

set aPDFdoc to current application’s PDFDocument’s alloc()’s initWithURL:aURL
set pCount to aPDFdoc’s pageCount()

set firstPage to (aPDFdoc’s pageAtIndex:0)
–>  (PDFPage) PDFPage, label 1

set anoList to (firstPage’s annotations()) as list
(*
{(PDFAnnotationMarkup) Type: ’Highlight’, Bounds: (81, 624) [434, 53]
, (PDFAnnotationSquare) Type: ’Square’, Bounds: (50, 419) [212, 162]
, (PDFAnnotationSquare) Type: ’Square’, Bounds: (301, 107) [244, 484]
}
*)

repeat with i in anoList
  set aBounds to i’s |bounds|()
  
  
log aBounds
  
(* {origin:{x:80.79, y:624.4106}, size:{width:433.6944, height:52.8918}} *)
  
(* {origin:{x:50.05553, y:419.1671}, size:{width:212.27807, height:162.3308}} *)
  
(* {origin:{x:300.6213, y:106.8405}, size:{width:244.0961, height:484.4566}} *)
  
end repeat

★Click Here to Open This Script 

2013/04/21 Skim 1.4.3で追加されたfavorite colorsにアクセス

オープンソースのPDFビューワー「Skim」の最新バージョン1.4.3で追加された属性「favorite colors」にアクセスするAppleScriptです。

applicationの属性値としてfavorite colorsが追加されました。

skim0.png

スクリプト名:Skim 1.4.3で最近使った色を取得
tell application “Skim”
  set aList to favorite colors
end tell

–> {{65535, 0, 0, 65535}, {65535, 32768, 0, 65535}, {65535, 65535, 0, 65535}, {0, 65535, 0, 65535}, {0, 0, 65535, 65535}, {65535, 0, 65535, 65535}}

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

結果は、{R(赤),G(緑),B(青),A(アルファ値)}のセットのリストで返ってきます。各値は16ビットの数値です。

skim1.png

skim2.png

色の値は16ビットなのでchoose colorでプレビューするときには簡単(アルファチャネルは無視)ですが、一般的なアプリケーションの多くでは8ビットの値で扱っているので、16ビット→8ビット変換のためにちょっとだけ計算を追加で行う必要があります。

スクリプト名:Skim 1.4.3の最近使った色をプレビュー
tell application “Skim”
  set aList to favorite colors
end tell

repeat with i in aList
  set {r, g, b, a} to i
  
set aCol to {r, g, b}
  
  
choose color default color aCol
  
end repeat

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2012/10/07 Skimでオープン中のPDFの現在のページの内容をOmniGraffleにペースト

オープンソースのPDFビューワー「Skim」でオープン中のPDFの表示中のページの内容をそのままOmniGraffleの現在表示中のページ(canvas)にペーストするAppleScriptです。

現在、PDFビューワーのうちScriptableなものといえばAdobe AcrobatとSkim。Acrobatはインストールしてもいいことがあまりないように(個人的に)感じるので、ほぼ知り合いにはSkimのインストールをお願いしています。Mac OS X標準添付のプレビュー.appは(そのままでは)AppleScriptからはコントロールできないので、Skimはおすすめです。

本AppleScriptはSkimでオープン中のPDFの、現在表示中のページの内容を取得して……

skim_to_omni1.png

OmniGraffleの現在表示中のページ(Canvas)にその内容をペーストします。

skim_to_omni2.png

Skimには、指定の座標内の内容を取得する「grab」コマンドがあるので、取得した内容をそのままOmniGraffleに持って行けばいいだろうかと考えて一度試してみたのですが……思ったようには動かず、結局地道に「Grabした内容を一度ファイルに書き出して、OmniGraffleに書き出したPDFを読み込む」というやり方に落ち着きました。

喫茶店でコーヒー1杯飲むぐらいの時間で作ったので、処理自体はかなり適当です。一時的にTemporary Items Folderに書き出したPDFファイルのゴミ捨て処理なども行っていません。現在表示中のページのみを処理するようにしてありますが、AppleScript的に一括処理を行うのであれば、Skimで表示中のPDFのすべてのページをループで処理してOmniGraffleにインポートするように書き換えるとよいでしょう。

スクリプト名:Skimでオープン中のPDFの現在のページの内容をOmniGraffleにペースト

set outFol to (path to temporary items from system domain) as string
set cName to do shell script “/usr/bin/uuidgen”

tell application “Skim”
  tell document 1
    tell current page
      set bList to bounds –{Left, Top, Right, Bottom} —> {0, Height, Width, 0}
      
set anImage to grab for bList –as PDF
    end tell
  end tell
end tell

set bbList to {contents of third item of bList, contents of second item of bList}

set target_file to outFol & cName
write_to_file(anImage, target_file, false) of me

makeShapeWithProperty(missing value, target_file, {0, 0}, bbList, “”, true) of omniGroupScriptLib

–指定画像ファイルを現在のドキュメントにインポートする
–Omni Groupの配布しているScriptから、関係ないルーチンとプロパティを削除してほぼそのまま使用
script omniGroupScriptLib
  
  
on makeShapeWithProperty(onCanvas, myFile, aPositionList, aSizeList, aURL, outLineFlag)
    using terms from application “OmniGraffle 5″
      tell application “OmniGraffle 5″
        tell document 1
          tell canvas 1
            set theShape to make new shape at front of graphics with properties {origin:aPositionList, thickness:0.5, fill:no fill, draws stroke:outLineFlag, size:aSizeList, draws shadow:false, autosizing:overflow}
            
            
set url of theShape to aURL
            
            
getPicture(theShape, myFile) of me
            
            
–後からこれらの属性をセットするのがミソ
            
set image sizing of theShape to stretched –ここが重要!!!
            
set size of theShape to aSizeList
            
            
return theShape
          end tell
        end tell
      end tell
    end using terms from – OmniGraffle
  end makeShapeWithProperty
  
  
  
– make the shape - I can’t get the import construct to work - so I make a shape and set its fill with the image.
  
on makeShape(onCanvas, myFile)
    using terms from application “OmniGraffle 5″
      tell application “OmniGraffle 5″
        tell onCanvas
          set theShape to make new shape at front of graphics with properties {origin:{0, 0}, thickness:0.0, fill:no fill, draws stroke:false, image scale:1, size:{20, 20}, draws shadow:false}
          
getPicture(theShape, myFile) of me
          
return theShape
        end tell
      end tell
    end using terms from – OmniGraffle
  end makeShape
  
  
– Get the dropped image, get it’s size and set it as a fill to the shape, and some (adjustable) settings.
  
on getPicture(theShape, myFile)
    set filePath to (myFile) as string
    
set posixPath to POSIX path of file filePath
    
try
      tell application “Image Events”
        launch
        
set this_image to open filePath
        
set the props_rec to the properties of this_image
        
copy (dimensions of props_rec) to {myX, myY}
        
close this_image
      end tell
    end try
    
    
using terms from application “OmniGraffle 5″
      tell application “OmniGraffle 5″
        ignoring application responses
          set image of theShape to posixPath
          
set image sizing of theShape to manual
          
set image scale of theShape to 0.5 ——-Retina Displayなので
          
set image offset of theShape to {0, 0}
          
set size of theShape to {myX, myY}
          
–select theShape
        end ignoring
      end tell
    end using terms from
  end getPicture
  
  
return theShape
  
end script

–ファイルの追記ルーチン「write_to_file」
–追記データ、追記対象ファイル、boolean(trueで追記)
on write_to_file(this_data, target_file, append_data)
  try
    set the target_file to the target_file as text
    
set the open_target_file to open for access file target_file with write permission
    
if append_data is false then set eof of the open_target_file to 0
    
write this_data to the open_target_file starting at eof
    
close access the open_target_file
    
return true
  on error error_message
    try
      close access file target_file
    end try
    
return error_message
  end try
end write_to_file

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2012/08/22 指定フォルダ内のPDFの空白ページ以外を個別に取り出して別フォルダに保存 v3

指定フォルダ内のPDFの空白ページ「以外」を個別に取り出して、別フォルダに保存するAppleScriptです。

HTMLコンテンツを大量にプリンタで印刷するのに、HTMLレンダラー「wkpdf」を用いて個別のPDFに書き出し、これを連結してまとめてプリンタに送ろうとしたときに必要で作ったものです。

wkpdfでレンダリングしたときに余白ができて、内容が2ページ目まであふれていないのに空白の2ページ目が作られるケースがありました。これに対策すべく……

(1)PDFのページ数を数える。1ページのPDFなら、出力先フォルダにそのまま(ページ数を振りつつ)コピー

(2)2ページ以上のPDFなら、skimでPDFをオープンして、各ページに存在する文字情報を取得。2ページ目以降に文字情報が存在していない場合には、グラフィックが存在している可能性があるため、個別にPDFに書き出して、Photoshopでオープンし画像のヒストグラムを取得。画像のヒストグラムにドットの反応がなければ、「真っ白なページだった」=「空白ページ」とみなして破棄。ドットの反応があれば、出力先フォルダに(ページ数を振りつつ)コピー

という動作を行います。

この前のバージョンでは、2ページ目への文字あふれしか検出できていなかったのですが、改良してグラフィック要素があふれた場合でも対応できるようにしました。

実戦投入して、便利に使えています。

なお、おおきなおともだちの皆様にはお分かりと思いますが、Photoshop CS3以降でなくともPhotoshop Elements(お安い)でも代用できます。

スクリプト名:指定フォルダ内のPDFの空白ページ以外を個別に取り出して別フォルダに保存 v3
set inFol to choose folder with prompt “処理対象のPDFが入っているフォルダを指定”

set dtPath to choose folder with prompt “出力先フォルダを選択”
set dtPathStr to dtPath as string

tell application “Finder”
  tell folder inFol
    set aFileList to (every file whose name ends with “.pdf”) as alias list
  end tell
end tell

–それぞれのPDFの1ページ目のみ抽出
repeat with i in aFileList
  set j to contents of i
  
set pNum to pdfCount(j) of me
  
if pNum = 1 then
    –ファイルをコピー、ファイルのリネーム?
    
tell application “Finder”
      set fRes to duplicate j to dtPath
      
set tmpName to name of fRes
      
      
set bName to retFileNameWithoutExt(tmpName) of me
      
set cName to bName & “_1.pdf”
      
      
set name of fRes to cName
    end tell
    
    
  else if pNum > 1 then
    –1ページ目以外のページを、空白でないかどうかチェックする
    
set outList to {1}
    
    
repeat with ii from pNum to 2 by -1
      set aRes to detectBlankPageFromPDF(j, ii) of me
      
if aRes = false then
        set the end of outList to ii
      end if
    end repeat
    
    
    
–空白でないページのみ切り出して出力
    
repeat with ii in outList –出力対象ページ番号が入ったリスト
      set jj to contents of ii
      
set aRes to trimPDFbyPage(j, dtPathStr, jj) of me –エラー時にはfalseが返る
      
    end repeat
    
    
  end if
end repeat

–PDFの指定ページのみトリミング
on trimPDFbyPage(aFile, outFol, pageNum)
  tell application “Skim”
    close every document
    
    
open aFile
    
    
tell document 1
      set cCount to count every page
      
if cCount < pageNum then return false
    end tell
    
    
tell document 1
      set aProp to properties
      
set aRes to info of aProp
      
set aName to file name of aRes
      
set bName to retFileNameWithoutExt(aName) of me
      
      
set cName to bName & “_” & (pageNum as string) & “.pdf”
      
      
tell page pageNum
        set bList to bounds
        
set anImage to grab for bList –type “PDF”
      end tell
    end tell
    
    
set target_file to outFol & cName
    
write_to_file(anImage, target_file, false) of me
    
    
close every document
    
  end tell
end trimPDFbyPage

–ファイル名から拡張子を外す
on retFileNameWithoutExt(fileNameStr)
  set fLen to length of fileNameStr
  
set revText to (reverse of (characters of fileNameStr)) as string –逆順テキストを作成
  
set anOffset to offset of “.” in revText
  
set fRes to text 1 thru (fLen - anOffset) of fileNameStr
  
return fRes
end retFileNameWithoutExt

–指定PDFのページ数をかぞえる
on pdfCount(aPDF)
  return ((do shell script (“ruby -e \”require ‘osx/cocoa’;include OSX;require_framework ‘Quartz’;print PDFDocument.alloc.initWithURL(NSURL.fileURLWithPath(” & (quoted form of POSIX path of aPDF) & “)).pageCount\”")) as number)
end pdfCount

on makeFN(aNum, aDigit)
  set aText to “00000000000″ & (aNum as text)
  
set aLen to length of aText
  
set aRes to text (aLen - aDigit) thru -1 of aText
  
return aRes
end makeFN

–ファイルの追記ルーチン「write_to_file」
–追記データ、追記対象ファイル、boolean(trueで追記)
on write_to_file(this_data, target_file, append_data)
  try
    set the target_file to the target_file as text
    
set the open_target_file to open for access file target_file with write permission
    
if append_data is false then set eof of the open_target_file to 0
    
write this_data to the open_target_file starting at eof
    
close access the open_target_file
    
return true
  on error error_message
    try
      close access file target_file
    end try
    
return error_message
  end try
end write_to_file

–指定PDFの指定ページが空白(真っ白)かどうか判定する
on detectBlankPageFromPDF(aFile, targPage)
  tell application “Skim”
    close every document
    
    
open aFile
    
    
tell document 1
      set cCount to count every page
      
set cDigit to length of (cCount as string)
      
      
set docName to name
      
      
tell page targPage
        set bList to bounds
      end tell
      
      
if cCount > 1 then
        
        
–指定ページに文字が存在するかチェック
        
tell page targPage
          set aProp to properties
          
set aText to first item of text of aProp
        end tell
        
        
if aText is not equal to “” then
          return false
        end if
      end if
      
      
tell page targPage
        set anImage to grab for bList –type “PDF”
      end tell
    end tell
    
    
close every document
    
  end tell
  
  
–指定ページ内容をテンポラリフォルダに書き出す
  
set outFol to (path to temporary items from system domain) as string
  
set docName to (do shell script “/usr/bin/uuidgen”) & “.pdf”
  
  
set target_file to outFol & docName
  
write_to_file(anImage, target_file, false) of me
  
  
do shell script “sync” –キャッシュされたままディスクに書かれていないことがあるので実行
  
  
  
–書き出したPDFをPhotoshopでオープンしてヒストグラムから描画物の存在を検出
  
–Photoshop Elementsでも代用可
  
tell application “Adobe Photoshop CS3″
    close every document saving no
    
open file target_file
    
tell current document
      set aList to histogram
    end tell
    
close every document saving no
  end tell
  
  
–テンポラリPDFを削除する
  
do shell script “/bin/rm -f “ & (quoted form of POSIX path of target_file)
  
  
set aRes to detectWhiteFromList(aList) of me
  
  
return aRes –空白だとtrueを、そうでない場合にはfalseを返す
  
end detectBlankPageFromPDF

–与えられたPhotoshopヒストグラム(256段階の明るさのピクセル数)から、その内容が真っ白かどうかを検出
on detectWhiteFromList(aList)
  set aLen to length of aList
  
  
set zeroF to true
  
repeat with i from 1 to (aLen - 1) –真っ白かどうかを検知している
    if item i of aList is not equal to 0 then
      set zeroF to false
      
exit repeat
    end if
  end repeat
  
  
return zeroF
  
end detectWhiteFromList

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/12/10 Skimで、現在表示中のページを別ファイルにPDF形式で書き出す

オープンソースのPDFビューワー「Skim」で、現在表示中のPDFのページを別のPDFに書き出すAppleScriptです。

最初は、現在表示中のページだけを残して、他のページを「削除する」AppleScriptを書いていたのですが、Skimではpageを削除できないことにあとから気付きました。

そこで、急遽「ページごとに別ファイルに書き出す」Scriptを機能ダウンさせて現在のページのみPDFで別ファイルに書き出すように変更。

スクリプト名:Skimで、現在表示中のページを別ファイルにPDF形式で書き出す
tell application “Skim”
  tell document 1
    set aBounds to selection bounds
    
tell current page
      set grabData to grab for aBounds as PDF
    end tell
  end tell
end tell

set newAlias to choose file name
write_to_file(grabData, newAlias, false) of me

–ファイルの追記ルーチン「write_to_file」
–追記データ、追記対象ファイル、boolean(trueで追記)
on write_to_file(this_data, target_file, append_data)
  try
    set the target_file to the target_file as text
    
set the open_target_file to open for access file target_file with write permission
    
if append_data is false then set eof of the open_target_file to 0
    
write this_data to the open_target_file starting at eof
    
close access the open_target_file
    
return true
  on error error_message
    try
      close access file target_file
    end try
    
return error_message
  end try
end write_to_file

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

こちらが、動かないほうのバージョンです。コンパイル(構文確認)も通るのですが、アプリケーション側がサポートしていないオブジェクトとコマンドの組み合わせだと動かないという、いい見本です。

スクリプト名:Skimで、現在表示中のページ以外をすべて削除する(ダメ)
–そもそも、pageをdeleteすることができなかった
–→ 現在のページだけをExportする方向で書き直し

tell application “Skim”
  tell document 1
    set curP to index of current page –現在表示中のページ番号(index)を取得
    
set totalP to count every page –全ページ数を取得
    
    
    
if totalP = 1 then
      display dialog “1ページしか存在しない書類は処理対象外です” buttons {“OK”} default button 1 with icon 1
      
return
    end if
    
    
if curP = 1 then
      –現在表示中のページが1ページ目だった場合の処理
      
delete (pages 2 thru -1)
      
    else if curP = totalP then
      –現在表示中のページが最終ページだった場合の処理
      
delete (pages 1 thru -2)
      
    else
      –その他 通常処理
      
delete (pages 1 thru (curP - 1))
      
delete (pages (curP + 1) thru -1)
      
    end if
    
  end tell
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2011/09/25 指定フォルダ内のPDFの1ページ目のみ取り出して別フォルダに保存 v2

指定フォルダ内のPDFの1ページ目のみ取り出して、別フォルダに1ページ目だけのPDFを保存するAppleScriptです。

オープンソースなのにAppleScript対応度のきわめて高いPDFビューワー「Skim」をコントロールして、PDFの指定ページ上にコンテンツが存在しないかのチェック、およびページ切り出しを行っています。

ここでいうPDFは、ドキュメントスキャナーで読み込んだPDFではなく、何らかのアプリケーションから書き出したPDF(文字情報が選択できる)を意図しています。

大量のHTMLを印刷する際に、1枚ずつプリンタに送ると時間がかかるため、CLIのHTMLレンダラー(wkpdf)にかけて大量のPDFを生成。この大量のPDFを1つのドキュメントにまとめてプリンタに送れば、印刷時間の圧倒的な短縮が可能になるのではないか、という話を実現する過程で作成したものです。

だいたいは思い通りに行ったのですが、誤算がひとつ。HTMLレンダラーが1ページ分のコンテンツも2ページにまたがってPDF出力(しかも2ページ目は空白)することが多く……単純に1ページ目のみ抽出しようとしても、今度は本当にHTMLの分量が多くて複数ページにまたがってレンダリングされている場合もあったために、単純作業で2ページ以降を捨てるのでは困るということになりました。

そこで、ほとんど文字情報から構成されるコンテンツであったため、2ページ目に何か文字の情報がないかSkimをコントロールしてAppleScriptでチェックし、存在しなければ1ページ目のみ抽出。存在している場合には抽出処理を行わないようにしました。

人間が目で見て確認しなくてよいので、作業の飛躍的な高速化を実現できました。もちろん、印刷もあっという間。

もし、文字情報が入っていない画像系のPDFが対象だったら……解像度を指定してPhotoshopで読み込み、ヒストグラムを取得するなどして情報の有無を判定すると楽ができてよいでしょう。

スクリプト名:指定フォルダ内のPDFの1ページ目のみ取り出して別フォルダに保存 v2
set inFol to choose folder with prompt “処理対象のPDFが入っているフォルダを指定”

set dtPath to choose folder with prompt “出力先フォルダを選択”
set dtPathStr to dtPath as string

tell application “Finder”
  tell folder inFol
    set aFileList to (every file whose name ends with “.pdf”) as alias list
  end tell
end tell

–それぞれのPDFの1ページ目のみ抽出
repeat with i in aFileList
  trimPDF(i, dtPathStr) of me
end repeat

–PDFの最初のページのみトリミング
on trimPDF(aFile, outFol)
  tell application “Skim”
    close every document
    
    
open aFile
    
    
tell document 1
      set cCount to count every page
      
set cDigit to length of (cCount as string)
      
      
set docName to name
      
      
tell page 1
        set bList to bounds
      end tell
      
      
if cCount > 1 then
        tell page 2
          set aProp to properties
          
set aText to first item of text of aProp
        end tell
        
        
if aText is not equal to “” then
          
          
display dialog “書類「” & docName & “」は、2ページ目に実際に内容が存在するため、2ページ目を削除せずそのままコピーします。”
          
          
tell application “Finder”
            set target_file to outFol & docName
            
            
duplicate aFile to file target_file
            
          end tell
          
          
return –ここが重要
          
        end if
      end if
    end tell
    
    
tell document 1
      tell page 1
        set anImage to grab for bList –type “PDF”
      end tell
    end tell
    
    
set target_file to outFol & docName
    
write_to_file(anImage, target_file, false) of me
    
    
close every document
    
  end tell
end trimPDF

on makeFN(aNum, aDigit)
  set aText to “00000000000″ & (aNum as text)
  
set aLen to length of aText
  
set aRes to text (aLen - aDigit) thru -1 of aText
  
return aRes
end makeFN

–ファイルの追記ルーチン「write_to_file」
–追記データ、追記対象ファイル、boolean(trueで追記)
on write_to_file(this_data, target_file, append_data)
  try
    set the target_file to the target_file as text
    
set the open_target_file to open for access file target_file with write permission
    
if append_data is false then set eof of the open_target_file to 0
    
write this_data to the open_target_file starting at eof
    
close access the open_target_file
    
return true
  on error error_message
    try
      close access file target_file
    end try
    
return error_message
  end try
end write_to_file

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2010/10/02 SkimでPDFをページごとに分割する

オープンソースのPDFビューワー「Skim」でPDF書類をページごとに分割するAppleScriptです。

たいていオープンソースのアプリケーションといえばAppleScriptへの対応はなかったり中途半端だったり、勘違いした実装を行っているようなもの(FireFoxあたりがその代表例)が普通ですが、このSkimは例外中の例外。バージョンアップとともにAppleScriptの対応度がアップするなど、なかなか見逃せないアプリケーションです。

複数のPDFを1つの書類にまとめる機能を持つものは多々あります。しかし、探してみると1つのPDF書類をページごとに分解する機能を持つものはそれほど見かけません。

調べてみたら、AdobeのAcrobat Reader、Smile SoftwareのPDF Pen、そしてSkimぐらい(以前はPDFtoolkitが使えたのですが、Mac OS X 10.4までしか対応していなかったので)。そのうち、AppleScriptに(まともに)対応しているのがPDFpenとSkim。フリーで入手できるものでいえばSkimしかありません。

そんなわけで、SkimをAppleScriptから制御してページごとにPDFを分解させてみました。

ちなみに、PDFpenには標準でPDFをページ単位に分解するAppleScriptが添付されており、PDFpenのScriptメニューから実行できるようになっていますが、同じデータを処理させてみたところSkimの方が高速に処理できました。

スクリプト名:SkimでPDFをページごとに分割する
set dtPath to path to desktop from user domain
set dtPathStr to dtPath as string

tell application “Skim”
  tell document 1
    set cCount to count every page
    
set cDigit to length of (cCount as string)
    
    
set docName to name
    
    
tell page 1
      set bList to bounds
    end tell
  end tell
  
  
repeat with i from 1 to cCount
    tell document 1
      tell page i
        set anImage to grab for bList –type “PDF”
      end tell
    end tell
    
    
set target_file to dtPathStr & makeFN(i, cDigit) of me & “_” & docName
    
write_to_file(anImage, target_file, false) of me
    
  end repeat
  
end tell

on makeFN(aNum, aDigit)
  set aText to “00000000000″ & (aNum as text)
  
set aLen to length of aText
  
set aRes to text (aLen - aDigit) thru -1 of aText
  
return aRes
end makeFN

–ファイルの追記ルーチン「write_to_file」
–追記データ、追記対象ファイル、boolean(trueで追記)
on write_to_file(this_data, target_file, append_data)
  try
    set the target_file to the target_file as text
    
set the open_target_file to open for access file target_file with write permission
    
if append_data is false then set eof of the open_target_file to 0
    
write this_data to the open_target_file starting at eof
    
close access the open_target_file
    
return true
  on error error_message
    try
      close access file target_file
    end try
    
return error_message
  end try
end write_to_file

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2010/03/30 Skim 1.3.5でsave命令のオプションが変更に

オープンソースのPDFビューワーなのになぜかAppleScript系の機能が充実している「Skim」

skim0.jpg

バージョン1.3.4から1.3.5へのアップデート時に、例によってAppleScript用語辞書をHTMLに書き出してdiff(Apple謹製のFileMerge。Xcode Toolsに入っている)で差分チェックを行ってみたところ、saveコマンドのオプションに変更が行われたことが明らかになりました。

実際にサンプルを書いて本当に使えるかどうかチェックしてみないと「使えるようになった」と結論づけることはできませんが、dviファイルといえば……TeX(テフ)ですか(汗) 使ったことはありませんが、昔……工学部の友人たちがこれでレポートを書かされて苦労していました。今はWordなどで提出できるようですが…………

skim1.jpg
▲FileMergeで差分チェックを行った結果

skim2.jpg
▲Skim 1.3.5のAppleScript用語辞書

2009/02/05 Skimでコメントつき注釈(note)の情報を取得する

Skimで、GUI側からコメント(extended text)つきの注釈(note)を作成し、その情報を取得してみました。

skim8.jpg

スクリプト名:Skimでコメントつき注釈(note)の情報を取得する
tell application Skim
  tell document 1
    tell note 1
      properties
    end tell
  end tell
end tell

> {type:anchored note, extended text:”なんてこったい!”, icon:comment icon, page:page 1 of document “InDesign CS3 スクリプティング ガイド AS.pdf” of application “Skim”, class:note, bounds:{453, 740, 469, 724}, text:”ほげほげーー”, color:{64639, 65535, 26043, 65535}}

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2009/02/05 Skimで注釈(note)を削除する

Skimで現在オープン中のPDF(document 1)の、指定ページ内の注釈(note)を削除します。

スクリプト名:Skimで注釈(note)を削除する
tell application Skim
  tell document 1
    tell page 1
      delete every note
    end tell
  end tell
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2009/02/05 Skimで注釈(note)を新規作成する

Skimで、現在オープン中のPDF(document 1)に対して、注釈(note)を作成します。意外とあっさりできてしまい、拍子抜けするほどです。

skim7.jpg

スクリプト名:Skimで注釈(note)を新規作成する
tell application Skim
  tell document 1
    tell page 1
      make new note with properties {type:text note, dash pattern:{}, font color:{0, 0, 0, 65535}, font size:36, bounds:{277, 573, 480, 532}, line style:solid line, font name:”LucidaGrande“, class:note, line width:1.0, text:”注釈だよー2“, color:{0, 65535, 26043, 65535}}
    end tell
  end tell
end tell
> note 1 of page 1 of document “InDesign CS3 スクリプティング ガイド AS.pdf” of application “Skim”

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2009/02/05 Skimで注釈(note)の情報を取得する

Skimで、PDF上にユーザーが作成した注釈(note)の情報を取得します。

skim6.jpg

スクリプト名:Skimで注釈(note)の情報を取得する
tell application Skim
  tell document 1
    tell note 1
      properties
    end tell
  end tell
end tell

> {type:text note, dash pattern:{}, font color:{0, 0, 0, 65535}, font size:36, bounds:{277, 573, 480, 532}, line style:solid line, page:page 11 of document “InDesign CS3 スクリプティング ガイド AS.pdf” of application “Skim”, font name:”LucidaGrande”, class:note, line width:1.0, text:”注釈だよー”, color:{64639, 65535, 26043, 65535}}

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2009/02/05 Skimで選択中の範囲をファイルに書き出す

Skimの選択ツールで選択している範囲(selection bounds)をPDFに書き出すAppleScriptです。

たとえば、AdobeがInDesignに添付している「InDesign CS3スクリプティング ガイドAS」をSkimでオープンし、選択ツールで範囲を選択し……本Scriptを実行すると、選択範囲が新規作成されたPDFファイルに書き出されます。

skim3.jpg

skim4.jpg

スクリプト名:Skimで選択中の範囲をファイルに書き出す
tell application Skim
  tell document 1
    set aBounds to selection bounds
    
tell page 4
      set grabData to grab for aBounds astype PDF
    end tell
  end tell
end tell

set newAlias to choose file name
write_to_file(grabData, newAlias, false) of me

ファイルの追記ルーチン「write_to_file」
追記データ、追記対象ファイル、boolean(trueで追記)
on write_to_file(this_data, target_file, append_data)
  try
    set the target_file to the target_file as text
    
set the open_target_file to open for access file target_file with write permission
    
if append_data is false then set eof of the open_target_file to 0
    
write this_data to the open_target_file starting at eof
    
close access the open_target_file
    
return true
  on error error_message
    try
      close access file target_file
    end try
    
return error_message
  end try
end write_to_file

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2009/02/05 Skimでアプリケーション自身の情報を取得する

Skimのアプリケーション自体の設定情報を取得します。Preferencesの画面とかなり一致している部分があり、気合いが入っていることが伺われます。

skim5.jpg

スクリプト名:Skimでアプリケーション自身の情報を取得する
tell application Skim
  properties
end tell
> {default note line widths:{text note line width:1.0, line note line width:2.0, freehand note line width:2.0, circle note line width:2.0, box note line width:2.0}, default note dash patterns:{text note dash pattern:{}, line note dash pattern:{}, freehand note dash pattern:{}, circle note dash pattern:{}, box note dash pattern:{}}, default note line styles:{text note line style:solid line, line note line style:solid line, freehand note line style:solid line, circle note line style:solid line, box note line style:solid line}, frontmost:false, default note icon type:note icon, default full screen view settings:{display box:media box, display mode:single page}, version:”1.2.1″, name:”Skim”, default note colors:{highlight note color:{65535, 65535, 0, 65535}, line note color:{0, 0, 65535, 65535}, circle note interior color:{0, 0, 0, 0}, circle note color:{65535, 0, 0, 65535}, box note color:{0, 65535, 0, 65535}, underline note color:{0, 32768, 0, 65535}, strike out note color:{65535, 0, 0, 65535}, text note color:{65535, 65535, 32768, 65535}, freehand note color:{65535, 0, 0, 65535}, text note font color:{0, 0, 0, 65535}, box note interior color:{0, 0, 0, 0}, anchored note color:{65535, 65535, 32768, 65535}}, default note start line style:no line ending, class:application, default view settings:{display box:crop box, auto scales:false, book:false, scale factor:1.0, display mode:single page continuous, displays page breaks:true}, default note end line style:open arrow line ending, background color:{32769, 32769, 32769, 65535}, full screen background color:{16384, 16384, 16384, 65535}}

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2009/02/05 SkimでPDFの指定ページ内の情報を取得する

Skimで、PDFの指定ページ内の情報を取得します。本文テキストが取得できるのが素敵です。

skim11.jpg

スクリプト名:SkimでPDFの指定ページ内の情報を取得する
tell application Skim
  tell document 1
    tell page 1
      properties
    end tell
  end tell
end tell

(*
{text:”Device Driver for
Mac OS X
Mac OS X用のデバイスドライバをUSB Mouseのドライバを例に
紹介します。
稲田元彦
inADA
2003.08.26
修正2003.12.05
Copyright (C) 2003 inADA.
All rights reserved.”, content bounds:{69, 615, 533, 70}, rotation:0, label:”1″, index:1, class:page, media bounds:{0, 842, 595, 0}, bounds:{0, 842, 595, 0}}
*)

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2009/02/05 SkimでPDFの各種情報を取得する

オープンソースのソフトウェアといえば、AppleScript非対応とかAppleScript対応機能の実装方法が間違っているとかAppleScript対応機能が機能していないといった話のオンパレードですが、例外のソフトウェアがひとつ。オープンソースのPDFビューワー「Skim」がそれです。

PDFビューワーといえば、Mac OS X標準装備の「Preview.app」があるので「何をいまさら」という感もないわけではありませんでしたが……ダウンロードしてびっくり、AppleScript対応機能がひじょうに充実。

ある意味、Skimは「最強のPDFビューワー」といっても過言ではありません。ページ数が分るとかそういう話は当然で、なんとPDF本文のテキストが取得できてしまいます。しかも、ページを指定して該当ページ上のテキストだけ取得するといった処理が可能です。

skim1.jpg

スクリプト名:SkimでPDFの各種情報を取得する
tell application Skim
  tell document 1
    properties
  end tell
end tell

> {modified:false, info:{producer:”Mac OS X 10.3.1 Quartz PDFContext”, encrypted:false, creation date:date “2003年 12月 6日 土曜日 2:55:13 PM”, modification date:date “2003年 12月 6日 土曜日 2:59:19 PM”, creator:”AppleWorks”, file name:”MacOSX_Driver1.pdf”, physical size:2.985984E+6, tags:{}, page count:15, page size:”21.0 x 29.7 cm (21.0 x 29.7 cm)”, allows printing:true, allows copying:true, rating:0.0, logical size:2.983359E+6, version:”1.4″, file size:”2.8 MB (2,983,359 bytes)”}, path:”/Users/maro/Documents/Develop/ドキュメント類/MacOSX_Driver1.pdf”, selection:{}, name:”MacOSX_Driver1.pdf”, text:”Device Driver for Mac OS X (中略) Copyright (C) 2003 inADA. All rights reserved.”, view settings:{display box:crop box, auto scales:false, book:false, scale factor:0.707115232944, display mode:single page continuous, displays page breaks:true}, active note:missing value, file:file “Cherry:Users:maro:Documents:Develop:ドキュメント類:MacOSX_Driver1.pdf”, class:document, current page:page 1 of document “MacOSX_Driver1.pdf” of application “Skim”, selection bounds:{0, 0, 0, 0}, selection page:missing value}

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に