Archive for the 'PDFAnnotation' Category

2017/06/16 指定PDFの最初のページに大量のスクウェアアノテーションを添付する

指定PDFの最初のページに大量のスクウェアアノテーションを添付するAppleScriptです。

他のGUIアプリケーションを併用せずQuartz Frameworkの機能を利用して、PDFに対するアノテーションの添付を行います。

square_anno1.png

PDFのアノテーションまわりはmacOS 10.13で大幅に変更されているため、本Scriptがそのまま10.13上でも動作することは期待していません。

AppleScript名:指定PDFの最初のページに大量のスクウェアアノテーションを添付する
– Created 2017-06-16 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “Quartz”
use framework “AppKit”
–http://piyocast.com/as/archives/4688

set aHFSPath to (choose file of type {“com.adobe.pdf”} with prompt “Select PDF”)
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 aPage to aPDFdoc’s pageAtIndex:0

set firstPage to (aPDFdoc’s pageAtIndex:0)

–Remove Annotation
my removeAnnotationFromPage:firstPage –Call by Reference

–Get PDF size by Point
set aBounds to aPage’s boundsForBox:(current application’s kPDFDisplayBoxMediaBox)
set aSize to |size| of aBounds

–Add Annotation
repeat with xNum from 30 to ((width of aSize) - 30) by 50
  repeat with yNum from 30 to ((height of aSize) - 30) by 50
    set squAnn to (current application’s PDFAnnotationSquare’s alloc()’s initWithBounds:{origin:{x:xNum, y:yNum}, |size|:{width:40, height:40}})
    (
squAnn’s setValue:(current application’s NSColor’s blueColor()) forAnnotationKey:(current application’s kPDFAnnotationKey_Color))
    (
squAnn’s setValue:(current application’s NSColor’s clearColor()) forAnnotationKey:(current application’s kPDFAnnotationKey_InteriorColor))
    (
firstPage’s addAnnotation:squAnn)
  end repeat
end repeat

–Save It
aPDFdoc’s writeToFile:aPOSIX

–Remove All Annotation from a Page. Call by Reference
on removeAnnotationFromPage:aPage
  set anoList to (aPage’s annotations()) as list
  
repeat with i in anoList
    (aPage’s removeAnnotation:i)
  end repeat
end removeAnnotationFromPage:

★Click Here to Open This Script 

2017/06/13 指定PDFの最初のページにアノテーションを追加する(テキストアノテーション)

指定のPDFの最初のページにテキストのアノテーションを追加するAppleScriptです。

だいたい想定していたとおりの処理はできているはずなんですが、Preview.app上で確認してみると想定していたのとは違う(クリックするとテキストが展開される)ので、まだいろいろ試してみないとダメっぽい感じです。

▼処理したPDFをPreview.appでオープンしたところ
pdf_ano1_resized.png

▼本AppleScriptで添付したアノテーションをクリックしたところ
pdf_ano2_resized.png

PDFのアノテーションまわりはmacOS 10.13で大幅に手が加わって変更されるので、このAppleScriptは単なるmacOS 10.10.x〜10.12.x上でのアノテーション追加実験ということになります。

AppleScript名:指定PDFの最初のページにアノテーションを追加する(テキストアノテーション)
– Created 2017-06-13 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.5″
use scripting additions
use framework “Foundation”
use framework “Quartz”
use framework “QuartzCore”
use framework “AppKit”
–http://piyocast.com/as/archives/4685

set aHFSPath to (choose file of type {“com.adobe.pdf”} with prompt “Choose a PDF”)
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 textAnnotation to current application’s PDFAnnotationText’s alloc()’s initWithBounds:{origin:{x:10, y:400}, |size|:{width:200, height:100}}
textAnnotation’s setType:(current application’s PDFAnnotationTextWidget)
textAnnotation’s setValue:“/FreeText” forAnnotationKey:(current application’s kPDFAnnotationKey_Subtype)
textAnnotation’s setValue:“Hello PDF” forAnnotationKey:(current application’s kPDFAnnotationKey_Contents)
textAnnotation’s setValue:(current application’s NSColor’s yellowColor()) forAnnotationKey:(current application’s kPDFAnnotationKey_Color)

firstPage’s addAnnotation:textAnnotation

aPDFdoc’s writeToFile:aPOSIX

★Click Here to Open This Script 

2017/06/12 PDFでテキスト検索してURLリンクのアノテーションを追加する

指定のPDFで指定のテキスト(list)を検索して、URLリンク(list)のアノテーションを追加するAppleScriptです。

PDFにアノテーションを追加するAppleScriptで、他のアプリケーションを併用せずにQuartz Frameworkの機能を利用するタイプのものを探してみたら、Shane StanleyがMacScripter.netに投稿したものだけが見つかりました。一応、読みやすく清書して一部変更したのと、日本語環境で日本語を含んだPDFに対して処理検証を行なったものを掲載しています。

ただ、Objective-Cで記述したサンプルについてもほとんど見つからないので、なかなか探すのに苦労させられています。むしろ、サードパーティのフレームワーク「PSPDFkit」あたりのほうがサンプルが充実しているので、用途によってはこちらも選択肢に入ってくることでしょう。

macOS 10.13, High SierraでPDFkitに大幅に手が入るようなので、そちらの登場を待てるようであれば、10.13のPDFkitを使ってもよいでしょう。

AppleScript名:PDFでテキスト検索してURLリンクのアノテーションを追加する
– Created 2016-01-05 10:17:51 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “Quartz”
–http://piyocast.com/as/archives/4682

set aPath to POSIX path of (choose file of type {“com.adobe.pdf”})
set pRes to my makeLinksInPDF:aPath forStrings:{“日本語 WordNet”, “日本語WordNet”} linkURLs:{“http://compling.hss.ntu.edu.sg/wnja/”, “http://compling.hss.ntu.edu.sg/wnja/”}

–指定のPDFの指定のキーワード群に対してURL群でリンクのアノテーションを追加する
on makeLinksInPDF:posixPath forStrings:listOfSearchStrings linkURLs:listOfLinkURLStrings
  set theURL to current application’s |NSURL|’s fileURLWithPath:posixPath
  
set thePDF to current application’s PDFDocument’s alloc()’s initWithURL:theURL
  
  
repeat with i from 1 to count of listOfSearchStrings
    
    
set searchString to item i of listOfSearchStrings
    
set linkURLString to item i of listOfLinkURLStrings
    
    
– get list of matches as PDFSelections
    
set theSels to (thePDF’s findString:searchString withOptions:0)
    
    
repeat with aSel in theSels
      set thePage to (aSel’s pages()’s objectAtIndex:0)
      
set theBounds to (aSel’s boundsForPage:thePage)
      
      
set theLink to (current application’s PDFAnnotationLink’s alloc()’s initWithBounds:theBounds) – make link with those bounds
      
set theAction to (current application’s PDFActionURL’s alloc()’s initWithURL:(current application’s |NSURL|’s URLWithString:linkURLString))
      
      (
theLink’s setMouseUpAction:theAction)
      
      
– set link’s appearance
      (
theLink’s setColor:(current application’s NSColor’s blueColor()))
      
set linkBorder to current application’s PDFBorder’s alloc()’s init()
      (
linkBorder’s setLineWidth:1.0)
      (
linkBorder’s setStyle:0)
      (
theLink’s setBorder:(linkBorder))
      (
theLink’s setShouldDisplay:true)
      
      
– add it to the page
      (
thePage’s addAnnotation:theLink)
    end repeat
  end repeat
  
  
– save the modified PDF
  
set oldName to theURL’s lastPathComponent()’s stringByDeletingPathExtension()
  
set newURL to (theURL’s URLByDeletingLastPathComponent()’s URLByAppendingPathComponent:(oldName’s stringByAppendingString:“-new”))’s URLByAppendingPathExtension:“pdf”
  
thePDF’s writeToURL:newURL
  
end makeLinksInPDF:forStrings:linkURLs:

★Click Here to Open This Script 

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