Acrobatでページ並べ替えをする作業が、ActionScriptを使うと劇的に短縮できることがわかったので、ここに覚え書きしておくことにします。
なお、当方が使用しているのは Acrobat Pro DC (2015 Release)ですが、movePageメソッドが使えるのならOK。
(チュートリアルによれば、Acrobat Pro 5.0以降でいける模様です。なお、残念ながら無料バージョンの Acrobat Reader では使えません。Action Script全般に関してそうですが)
#どういうときに movePage メソッドが必要なのか
個人的に、なぜこれが必須になったか、という例を挙げることにしましょう。
ズバリ、「本バッサリ裁断してスキャンかけた後、本のPDFを作成するとき」です。
<自分が困ったケース>
- 本の末尾には、必ず索引がついているものです。ところが、往々にして日本語の本では、索引の部分だけ、ページが逆順になっていることがあります。
例えば、[索引3]→[索引2]→[索引1]→奥付→裏表紙、という順番になっているケースがあるんです。日本語の本に多いです。
PDFにしたとき、これが見づらくて仕方ありません。
だから、この最後の索引の部分だけ、[索引1]→[索引2]→[索引3]→奥付→裏表紙、という形に並べ替えたかったのです。
- 両面スキャンすると、片面だけどうしても横筋が入ってしまう現象が発生しました。読み取り部分をクリーンしてみたものの、効果ナシ。
じゃあ2ページごとに横筋が入ってるPDFで我慢できるか?と言うところなのですが。実際に見てみたら分かると思いますが、これ、ものーっすごく不愉快です。2ページごとにイライラさせられるのは必定です。
じゃあ、どうするか。
スキャナーを2回回します。片面だけでやれば、なぜか横筋が入らなかったのです。すぐにスキャナを新調・修理に出すという状況下になかったので、コレで凌ぐしかなかったのです。
最初は、1ページから片面で表だけを読み取らせる。これで出来上がるのが
1, 3, 5, 7, 9, 11, 13, … (最後-1) :奇数ページ(正順)だけからなるPDF。
次は、裏返して最後のページから、片面で裏だけを読み取らせる。これで出来上がるのが
(最後), (最後-2), (最後-4), … , 8, 6, 4, 2 :偶数ページ(逆順)だけからなるPDF。
この2つのPDFを単純結合したら、
1, 3, 5, 7, 9, 11, 13, … (最後-1), (最後), (最後-2), (最後-4), … , 8, 6, 4, 2 というPDFが出来上がります。
これを、
1, 2, 3, 4, 5, 6, 7, 8, 9, …, (最後-2), (最後-1), (最後) というふうに、普通の順番に並べ替えたかったのです。
いろいろとネットを捜索した結果、
for (i = this.numPages - 1; i >= 0; i--) this.movePage(i);
という処理を見つけました。
Acrobat で ActionScript を実行させる方法は、[ツール]―[アクションウィザード]―[新規アクション]。
左ペインの[その他のツール]をクリック、[Javascriptを実行]をクリックすると、右ペインに勝手に「Javascriptを実行」のメニューが追加されるはずです。
その真ん中くらいにある「設定を指定」をクリック。
すると、JavaScriptエディターが飛び出してきます。そこに、コードを書く。書いたらOKで閉じる。で、[保存]を押すとアクション名と説明を入力させる画面が出てきます。
そこでOKしたら、アクションリストの一番下、カスタムコマンドという所にそのメニューがポンと追加されているはずです。
これを実際に作動させてみると、確かに全てのPDFのページが逆になったので、ビックリしました
ただ、この情報だけでは、自分のやらせたい処理をどう実現したら良いのか分からない・・・
どうすればよいかわからない中、Action Script の チュートリアルにたどり着きました。これが、勝因を切り開く結果となりました。
#Action Scriptのチュートリアル
JavaScript™ for Acrobat® API Reference
Adobe® Acrobat® SDK
April 2007 Version 8.1
https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/js_api_reference.pdf
ここのp.324に、movePage メソッドの説明がありました。
これがものすごく重要な情報で、つまり、文法が分かったのです。
movePage( 第1引数, 第2引数 )
第1引数に、動かしたいページ番号を入れる。(省略した場合は最初のページ)
第2引数に、「どのページの後に入れるか」のそのページ番号を入れる。(省略した場合は最後のページ)
注意点は、0基準なので、ページ番号を -1 してやらなければならない、と。
例えば Acrobatで p.10 と表示されていたら、それは ActionScript 側では p.9 として認識されている、ということですね。
#ではいよいよ実装
-
PDFの特定のページ箇所だけ、順番を逆にする方法
例えば、PDFのAcrobat表記で「654, 655, 656, 657」ページだけ「657, 656, 655, 654」にしたい、とします。
AcrionScript側で認識している番号に [ ] を付けて表すことにします。
1回目:[656] を [652] の後へ →「657, 654, 655, 656」
2回目:[656] を [653] の後へ →「657, 656, 654, 655」
3回目:[656] を [654] の後へ →「657, 656, 655, 654」
よって、求める ActionScript は、次のようになります。
StartPage = 654; /*ここは逆にしたい(Acrobatでの)開始ページを指定*/
EndPage = 657; /*ここは逆にしたい(Acrobatでの)終了ページを指定*/
MPN = EndPage - 1;
MoveTimes = EndPage - StartPage;
for (i = 0; i < MoveTimes; i++) this.movePage(MPN, StartPage - 2 + i);
-
1, 3, 5,…,(最後-1),(最後),(最後-2),(最後-4),…, 8, 6, 4, 2 となっているPDFを、
1, 2, 3, 4, 5, 6, 7, 8, 9, …, (最後-2), (最後-1), (最後) と普通に並べ替える方法
小さい例で考えると一般化しやすいですね。
PDFのAcrobat表記「1, 3, 5, 6, 4, 2」を「1, 2, 3, 4, 5, 6」にすると考えると、
1回目:[5] を [0] の後へ →「1, 2, 3, 5, 6, 4」
2回目:[5] を [2] の後へ →「1, 2, 3, 4, 5, 6」
理解を確実にするために、もう1個増やしましょうか。
PDFのAcrobat表記「1, 3, 5, 7, 8, 6, 4, 2」を「1, 2, 3, 4, 5, 6, 7, 8」にすると考えると、
1回目:[7] を [0] の後へ →「1, 2, 3, 5, 7, 8, 6, 4」
2回目:[7] を [2] の後へ →「1, 2, 3, 4, 5, 7, 8, 6」
3回目:[7] を [4] の後へ →「1, 2, 3, 4, 5, 6, 7, 8」
これで、構造が見えました。よって、求める ActionScript は、次のようになります。
MoveTimes = this.numPages / 2 - 1;
MPN = this.numPages - 1;
for (i = 0; i < MoveTimes; i++) this.movePage(MPN, 2*i);
たったこれだけで終わってしまう・・・
-
2, 1, 4, 3, …,(最後-2),(最後-3),(最後),(最後-1) となっているPDFを、
1, 2, 3, 4, 5, 6, 7, 8, 9, …, (最後-2), (最後-1), (最後) と普通に並べ替える方法
これ、主に日本語の "左から開く形の和書PDFあるある" です。
2ページ1面開きでコピーした後、何らかの仕掛けを使って、真ん中でそのPDFをブッタ切る、ということをやることがあります。この手が使えたら、コピーする手間が半分で済みますから。
で、それで機械的にプログラムで真ん中で2つにブッタ切った時、必ず発生する形です。
プログラムで真っ二つにブッタ切る方法は、例えば私が知ってる限りでは
[方法1] muPDFをダウンロードして適当なフォルダに格納した後、コマンドプロンプトを呼び出して、
mutool poster -x 2 (真ん中でブッタ切りたいPDF名).pdf (出力させたいPDFを名).pdf
と書いてポンと押してやる方法。
[方法2]PDFの印刷のプロパティで「ポスター(2枚)」にして出力させることで、半分に分割することができます。たしか、99%とか98%にしてやらないとちゃんと半分に切れてくれなかったはずです。
[方法3]TeXで \includepdf[angle=0, viewport=0mm 0mm 128.5mm 182mm, pages=\thepg]{\pdffn} というようにページの半分の箇所を指定して、実際はページの大きさは変わってないけど、左半分、右半分にフォーカスを移して、1ページづつになっているように見せかける、という技法
この3つの方法、探せば必ずどこかに書いてある方法です。私、これをすべて試したのですが、この不具合は解消しなかったのです。
なら、どうしていたのか。
Acrobatの画面を見ながら、マウスのドラッグでいちいち偶数ページを2個前に持ってって・・・、ってのを、PDF丸ごと延々とやるしかなかったのです😂。本が800ページとかになると、400回もこの作業をやらなければいけなかったのです。・・・苦痛以外の何物でもありませんでした
しかし、これも、いとも簡単に済んでしまうことが、判明してしまったのです。
小さい例で考えたら構造が見やすくなります。
PDFのAcrobat表記「2, 1, 4, 3, 6, 5」を「1, 2, 3, 4, 5, 6」にすると考えると、
1回目:[1] を [-1] の後へ →「1, 2, 4, 3, 6, 5」
2回目:[3] を [1] の後へ →「1, 2, 3, 4, 6, 5」
3回目:[5] を [3] の後へ →「1, 2, 3, 4, 5, 6」
1~6ページまでをやるとしたら、6/2=3回、開始ページから始まって、+2づつインクリメントしてやればいい、ってことですね。
よって、求める ActionScript は、次のようになります。
StartPage = 8; /*ここは開始したい(Acrobat上の)開始ページを指定*/
EndPage = 493; /*ここは終了したい(Acrobat上の)終了ページを指定*/
MoveTimes = ((EndPage - StartPage)+1)/2;
for (i = 0; i < MoveTimes; i++) this.movePage(StartPage+2*i, StartPage+2*(i-1));
今まで苦労していたのは、一体何だったのか・・・・
なんで、なんで、これにもっと早く気づかなかった ―――――――――――
もっと早くにAcrobatのJavascript操作という可能性に気が付き、ActionScriptにチャレンジするべきでした。多分100時間くらいムダにしていると思います
# あとがき
少量であれば手作業でもなんとかなると思いますが、自炊PDFが大量になってくると、死ねる作業量になってきます。600ページとか800ページの本が何十冊もあると。
Action Script があるとないでは、天地の差がついてくるでしょう。
今まで、手作業でページ整列作業をやっていただけに、確信を持って、そう言えます。
まさにAcrobat Proを使う利点に、初めて目覚めました。
いろいろとネットを調べ回ったのですが、movePagesについて書いているドキュメントがなかったので、ここにageておくことにします。
自分と同じような作業に悩んでいる人にとって、確実に作業時間を爆縮することでしょう。
どなたかの朗報にならんことを祈りつつ。
(2020/12/16 追記) 新たなテクニックを1つ、追記しておくことにします。 #指定間のページ内の、奇数のページだけを削除する方法 deletePagesを使うと、ページ削除ができます。 ![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463205/841683f6-0295-7667-8e52-bada9eaf58f1.png)
/* 指定ページ間内の、奇数のページだけを削除するスクリプト*/
StartPage = 2; /* Acrobat上に出ている開始ページ-1(0頁スタートで考える)を指定(よって、必ず偶数)*/
EndPage = 1566; /* Acrobat上に出ている終了ページ-1(0頁スタートで考える)を指定(よって、必ず偶数)*/
MoveTimes = (EndPage - StartPage)/2;
for (i = 0; i < MoveTimes; i++) {
deletePage = EndPage-2*i;
this.deletePages(deletePage);
}
注意点は、Acrobat Proで4ページ、と表示されていたら、ActionScriptの方ではそれは3ページとして認識されている、ということです。(0ページがスタートとみなされている)
DeletePages
の文法構造上、1枚1枚削除するしか方法がありませんでした。
1500ページの文書だと、15分くらいかかってしまいます。それでも、手作業に比べれば断然マシだと言えます。
(必ず奇数)としましたが、if文つけて分岐させれば、偶数でも奇数でも対応できるようになります。メンドクサイのでしてないだけです。
分岐バージョンは、下の参考ページの方のほうが詳しいです。
参考にしました。ありがとうございます。 ・Acrobat Pro DCのスクリプトについてのメモ https://qiita.com/tetsuya-k/items/eb37668d559ba98d22ac