Action Scriptを使ったら、PDFのページ並べ替え作業が劇的に短縮できる！

　Acrobatでページ並べ替えをする作業が、ActionScriptを使うと劇的に短縮できることがわかったので、ここに覚え書きしておくことにします。
　なお、当方が使用しているのは Acrobat Pro DC (2015 Release)ですが、movePageメソッドが使えるのならOK。
（チュートリアルによれば、Acrobat Pro 5.0以降でいける模様です。なお、残念ながら無料バージョンの Acrobat Reader では使えません。Action Script全般に関してそうですが）

#どういうときに movePage メソッドが必要なのか
　個人的に、なぜこれが必須になったか、という例を挙げることにしましょう。
　ズバリ、「本バッサリ裁断してスキャンかけた後、本のPDFを作成するとき」です。

＜自分が困ったケース＞
1. 本の末尾には、必ず索引がついているものです。ところが、往々にして日本語の本では、索引の部分だけ、ページが逆順になっていることがあります。
　例えば、<b>[索引3]→[索引2]→[索引1]→奥付→裏表紙</b>、という順番になっているケースがあるんです。日本語の本に多いです。
　PDFにしたとき、これが見づらくて仕方ありません。 
　だから、この最後の索引の部分だけ、<b><font color=red>[索引1]→[索引2]→[索引3]→奥付→裏表紙</font></b>、という形に並べ替えたかったのです。<br>
2. 両面スキャンすると、片面だけどうしても横筋が入ってしまう現象が発生しました。読み取り部分をクリーンしてみたものの、効果ナシ。
　じゃあ2ページごとに横筋が入ってるPDFで我慢できるか？と言うところなのですが。実際に見てみたら分かると思いますが、これ、ものーっすごく不愉快です。2ページごとにイライラさせられるのは必定です。

　じゃあ、どうするか。
　スキャナーを2回回します。片面だけでやれば、なぜか横筋が入らなかったのです。すぐにスキャナを新調・修理に出すという状況下になかったので、コレで凌ぐしかなかったのです。

　最初は、1ページから片面で表だけを読み取らせる。これで出来上がるのが
　<b>1, 3, 5, 7, 9, 11, 13, …　(最後-1)　：奇数ページ(正順)だけからなるPDF。</b>

　次は、裏返して最後のページから、片面で裏だけを読み取らせる。これで出来上がるのが
　<b>(最後), (最後-2), (最後-4), …　, 8, 6, 4, 2　：偶数ページ(逆順)だけからなるPDF。</b>
　
　この２つのPDFを単純結合したら、
　<b>1, 3, 5, 7, 9, 11, 13, …　(最後-1), (最後), (最後-2), (最後-4), …　, 8, 6, 4, 2</b> というPDFが出来上がります。
　これを、
　<b><font color=red>1, 2, 3, 4, 5, 6, 7, 8, 9, …, (最後-2), (最後-1), (最後)</font></b> というふうに、普通の順番に並べ替えたかったのです。

　いろいろとネットを捜索した結果、

```actionscript:全てのページを逆さまにしてしまうコード
for (i = this.numPages - 1; i >= 0; i--) this.movePage(i);
```

　という処理を見つけました。

　Acrobat で ActionScript を実行させる方法は、[ツール]―[アクションウィザード]―[新規アクション]。
　左ペインの[その他のツール]をクリック、[Javascriptを実行]をクリックすると、右ペインに勝手に「Javascriptを実行」のメニューが追加されるはずです。
　その真ん中くらいにある「設定を指定」をクリック。
　すると、JavaScriptエディターが飛び出してきます。そこに、コードを書く。書いたらOKで閉じる。で、[保存]を押すとアクション名と説明を入力させる画面が出てきます。
　そこでOKしたら、アクションリストの一番下、カスタムコマンドという所にそのメニューがポンと追加されているはずです。


　これを実際に作動させてみると、確かに全てのPDFのページが逆になったので、ビックリしました:upside_down:
　ただ、この情報だけでは、自分のやらせたい処理をどう実現したら良いのか分からない・・・:disappointed_relieved:

　どうすればよいかわからない中、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 メソッドの説明がありました。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463205/569e5e7c-b9d2-8325-a23d-faedf949186b.png)

これがものすごく重要な情報で、つまり、文法が分かったのです。

<b> movePage( 第1引数, 第2引数 )</b>
　第1引数に、動かしたいページ番号を入れる。(省略した場合は最初のページ)
　第2引数に、「どのページの後に入れるか」のそのページ番号を入れる。（省略した場合は最後のページ）

　<font color=red>注意点は、0基準なので、ページ番号を -1 してやらなければならない</font>、と。
　例えば Acrobatで p.10 と表示されていたら、それは ActionScript 側では p.9 として認識されている、ということですね。


#ではいよいよ実装
- <b>PDFの特定のページ箇所だけ、順番を逆にする方法</b><br>
　例えば、PDFのAcrobat表記で「654, 655, 656, 657」ページだけ「657, 656, 655, 654」にしたい、とします。<br>　AcrionScript側で認識している番号に [　] を付けて表すことにします。<br>
　　1回目：[656] を [652] の後へ　→「657, 654, 655, 656」<br>
　　2回目：[656] を [653] の後へ　→「657, 656, 654, 655」<br>
　　3回目：[656] を [654] の後へ　→「657, 656, 655, 654」<br>
 
　よって、求める ActionScript は、次のようになります。

```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);
```
<br>

- <b>1, 3, 5,…,(最後-1),(最後),(最後-2),(最後-4),…, 8, 6, 4, 2</b> となっているPDFを、<br>
<b><font color=red>1, 2, 3, 4, 5, 6, 7, 8, 9, …, (最後-2), (最後-1), (最後)</font></b> と普通に並べ替える方法<br>

　小さい例で考えると一般化しやすいですね。
　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 は、次のようになります。

```actionscript:「奇数(順)＋偶数(逆)」を１から順序よく整列させるコード
MoveTimes = this.numPages / 2 - 1;
MPN = this.numPages - 1;
for (i = 0; i < MoveTimes; i++) this.movePage(MPN, 2*i);
```
<br>
たったこれだけで終わってしまう・・・
<br><br>


- <b>2, 1, 4, 3, …,(最後-2),(最後-3),(最後),(最後-1)</b> となっているPDFを、<br>
<b><font color=red>1, 2, 3, 4, 5, 6, 7, 8, 9, …, (最後-2), (最後-1), (最後)</font></b> と普通に並べ替える方法<br>

　これ、主に<b>日本語の "左から開く形の和書PDFあるある" </b>です。

　2ページ1面開きでコピーした後、何らかの仕掛けを使って、真ん中でそのPDFをブッタ切る、ということをやることがあります。この手が使えたら、コピーする手間が半分で済みますから。

　で、それで機械的にプログラムで真ん中で2つにブッタ切った時、必ず発生する形です。

　プログラムで真っ二つにブッタ切る方法は、例えば私が知ってる限りでは

　[方法1] muPDFをダウンロードして適当なフォルダに格納した後、コマンドプロンプトを呼び出して、

```muPDF:PDFを真っ二つに割るコマンド
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ページづつになっているように見せかける、という技法

　この３つの方法、探せば必ずどこかに書いてある方法です。私、これをすべて試したのですが、この不具合は解消しなかったのです。

　なら、どうしていたのか。

　Acrobatの画面を見ながら、マウスのドラッグでいちいち偶数ページを2個前に持ってって・・・、ってのを、PDF丸ごと延々とやるしかなかったのです😂。本が800ページとかになると、400回もこの作業をやらなければいけなかったのです。・・・苦痛以外の何物でもありませんでした:triumph:

　しかし、これも、いとも簡単に済んでしまうことが、判明してしまったのです。

　小さい例で考えたら構造が見やすくなります。
　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 は、次のようになります。

```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));
```




今まで苦労していたのは、一体何だったのか・・・・:sob:
<br>
<br>
なんで、なんで、これにもっと早く気づかなかった ―――――――――――
もっと早くにAcrobatのJavascript操作という可能性に気が付き、ActionScriptにチャレンジするべきでした。多分100時間くらいムダにしていると思います:weary:


#　あとがき
　少量であれば手作業でもなんとかなると思いますが、自炊PDFが大量になってくると、死ねる作業量になってきます。600ページとか800ページの本が何十冊もあると。
　Action Script があるとないでは、天地の差がついてくるでしょう。
　
　今まで、手作業でページ整列作業をやっていただけに、確信を持って、そう言えます。
　まさにAcrobat Proを使う利点に、初めて目覚めました。
　いろいろとネットを調べ回ったのですが、movePagesについて書いているドキュメントがなかったので、ここにageておくことにします。
　
　自分と同じような作業に悩んでいる人にとって、確実に作業時間を爆縮することでしょう。
　どなたかの朗報にならんことを祈りつつ。:pray:




<br>
(2020/12/16 追記)
新たなテクニックを1つ、追記しておくことにします。
#指定間のページ内の、奇数のページだけを削除する方法
　deletePagesを使うと、ページ削除ができます。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463205/841683f6-0295-7667-8e52-bada9eaf58f1.png)


```actionscript:指定ページ間内の、奇数のページだけを削除するスクリプト
/* 指定ページ間内の、奇数のページだけを削除するスクリプト*/
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);
}
```
　注意点は、<font color=red>Acrobat Proで4ページ、と表示されていたら、ActionScriptの方ではそれは3ページとして認識されている、ということです。<b>（0ページがスタートとみなされている）</b></font>
　```DeletePages``` の文法構造上、1枚1枚削除するしか方法がありませんでした。
1500ページの文書だと、15分くらいかかってしまいます。それでも、手作業に比べれば断然マシだと言えます。
　(必ず奇数)としましたが、if文つけて分岐させれば、偶数でも奇数でも対応できるようになります。メンドクサイのでしてないだけです。
　分岐バージョンは、下の参考ページの方のほうが詳しいです。

<br>
参考にしました。ありがとうございます。
・Acrobat Pro DCのスクリプトについてのメモ
https://qiita.com/tetsuya-k/items/eb37668d559ba98d22ac