PDF英文自動整形 by Python【初心者向き自動化サンプル】

# 目次
- 概要
- モチベーション
- 環境
- 手法
- 実装例
- 補足（本当に必要か？）
- まとめ
- 参考文献

# 概要
PDFの英語文献を読む際、一部をコピーして貼り付けたいことありますよね。
しかし、コピーしたテキストに、不要な改行やハイフネーション(行の末尾に収まりきらない単語があるときに、単語の前半の末尾にハイフン（-）を記して改行し、後半を次行の冒頭に送ること[[1]](https://e-words.jp/w/%E3%83%8F%E3%82%A4%E3%83%95%E3%83%8D%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3.html))が含まれていることも多いです。
そのため、それらを自動で削除してつるっと整形するプログラムを作ろうという趣旨の記事です^^
(しかし、「補足」で後述しますが、既存のサービスは使えば十分なケースが多いかもしれません。)

# モチベーション
1. 論文など英文をPDFで読む際に、一部意味の分かりにくい部分を翻訳にかけたいことがあります。その際に、忌々しいフォーマットの乱れ（不要な改行やハイフネーション）があると翻訳精度が落ちるため。
2. 適度な自動化のサンプルとして以前このプログラムを作ったので、私がQiitaに最初の投稿をする題材としてちょうど良さそうだったため。

# 環境
Windows：バッチファイル（.bat）を用いてPythonスクリプトの実行を行います。

# 手法
### プログラム利用の流れ
1. 対象の英文をコピー
1. 「Windowsキー + R」（ファイル名を指定して実行）
1. shaper（スクリプト名）と入力+Enter：スクリプトの実行
1. スクリプトが実行され、クリップボードのテキストを整形した結果を、クリップボードに返す
1. 整形されたテキストを、適宜張り付けして使用

### 作るファイル・スクリプト
こいつらはMyCommandなどの名前のディレクトリにまとめておいておくとよいでしょう。
- `shaper.py`：実際に整形処理を行うpythonスクリプト
- `shaper.bat`：バッチファイル。こいつで、`shaper.py`を実行させます。

### 下準備
バッチファイルを`Win+R`（実行ダイアログ）から、起動するには、そのバッチファイルをシステムのパスが通っているディレクトリに配置する必要があります。次の2つの方法から好きな方をお選びください。
1. `C:\Windows` ディレクトリにバッチファイルを置く
    - `C:\Windows` はデフォルトでシステムパスに含まれています。従って、バッチファイルをここに置くと、`Win+R`からその名前で直接実行することが可能です。
    - ただし、セキュリティや整理の観点から、`C:\Windows` フォルダに直接ファイルを置くことは一般的に推奨されないと聞いたことがある気がします。
1. 環境変数にディレクトリを追加する
    - `D:\MyCommand` のようなカスタムフォルダにバッチファイルを置いている場合（私はこっち）、そのディレクトリ（フォルダ）をシステムの環境変数 PATH に追加する必要があります。
    - 環境変数に追加する方法は、[こちら](https://atmarkit.itmedia.co.jp/ait/articles/1805/11/news035.html)[[2]](https://atmarkit.itmedia.co.jp/ait/articles/1805/11/news035.html)などを参照なさってください。


# 実装例
それでは、2つのファイルの実装例を紹介します。
### shaper.bat
```bat:shaper.bat
@echo off
call \path\to\Anaconda3\Scripts\activate.bat ::Anaconda利用の場合のみ
python.exe D:\MyCommands\shaper.py
```
- `@echo off`：それ以下に記述されるコマンドをコンソール画面に表示させない。`@`は、その行のコマンド自体をコマンドプロンプトに表示させない。
- `call \path\to\Anaconda3\Scripts\activate.bat`：私は、PythonをAnaconda環境で利用しているので、call コマンドを使用して Anaconda の環境をアクティベートする必要があります。Windowsに直接Pythonをインストールしている場合は、不要です。
- `python.exe D:\MyCommands\shaper.py`：スクリプト実行。フルパスで指定してあげましょう。

### shaper.py
クリップボードの操作でpyperclipモジュール[[3]]((https://pypi.org/project/pyperclip/))を使用しますので、インストールしていない場合は`pip install pyperclip`などのコマンドでインストールしましょう。
コメントですべて説明してしまったので、何をしているかはコメントを見て下さい。
```python:shaper.py
import pyperclip

text = pyperclip.paste()

## テキストを行に分割し、それぞれの行の端から不要な空白を取り除く
# なぜか、キャリッジリターン('\r')が入っている場合があるので、strip()で消している。
# strip()は、文字列の先頭と末尾から、引数で指定した文字を取り除くメソッド。
# 引数なしデフォルトではスペース、タブ、キャリッジリターン（\r）、ラインフィード（\n）などの空文字を取り除く
lines = [line.strip() for line in text.split('\n')]

# ここで、空行を取り除いてから、各行を、空白を区切り文字として連結
formatted_text = ' '.join(line for line in lines if line)

## ハイフネーションの処理
# '- 'のように区切られてしまうケースを除去
formatted_text = formatted_text.replace('- ', '')

# 連結した文字列をクリップボードにコピー
pyperclip.copy(formatted_text)

```
### 実行例
実行前テキスト
```
While this support requirement does
not establish uniqueness (some equations may not

be independent), the method of analytic continua-
tion has been used [9] to show that, under these

conditions, multiple solutions are very rare.
```
実行後テキスト
```
While this support requirement does not establish uniqueness (some equations may not be independent), the method of analytic continuation has been used [9] to show that, under these conditions, multiple solutions are very rare.
```

# 補足（本当に必要か？）
ここまで記事を書いておきながら、実は、既存のサービスで大抵のフォーマットの乱れ問題は解決できます。
1. [Shaper](https://dream-exp.net/shaper/)[[4]](https://dream-exp.net/shaper/)：このWebアプリを使うとよいと思います。唯一難癖をつけるとしたら、「DeepLで翻訳」ボタンを押すと毎回新しいタブを開くのが少し面倒でしょうか？その点については、紙一重で自作スクリプトの方が優位性があるかもしれません。
1. なんなら、Googleの検索バーに張り付けるだけで、不要な改行はなくしてくれます。（ただし、ハイフネーションは無理）

# まとめ
自分で作るより、「Shaper使えばよくない？」というツッコミは許容しますw が、ニッチなタスクを自動化したいときなど、バッチファイルを利用した簡単な自動化はたまに使いますので、その手習いとしてはちょうど良いのではないでしょうか？
余談ですが、自分でスクリプト名を決めるとき、テキトーにshaperとしたのですが、Webアプリの方も完全に同じ名前でしたね...


# 参考文献
1. [ハイフネーション 【hyphenation】](https://e-words.jp/w/%E3%83%8F%E3%82%A4%E3%83%95%E3%83%8D%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3.html)
1. [Path環境変数を設定](https://atmarkit.itmedia.co.jp/ait/articles/1805/11/news035.html)
1. [pyperclip](https://pypi.org/project/pyperclip/)
1. [Shaper](https://dream-exp.net/shaper/)
1. [退屈なことはPythonにやらせよう](https://www.oreilly.co.jp/books/9784873117782/)