前提
- たくさんあるhtmlファイルの加工、編集をしたい。
- 環境はWindows 10.
- Emacsは入ってます。バージョン26.3.
- MSYS2も入っていてBash使用可能。
- しかしPython等のお手軽スクリプト言語の実行環境は無し。MicrosoftのPowershellやその他スクリプト言語には不慣れ。
ということでEmacsのDOM処理用関数を使うワンライナーを書くことにしました。
例題
カレントディレクトリにある拡張子htmlのファイルを開いてid="my-content"をもつ要素だけを抽出し、テキスト化して拡張子.txtのファイルに保存する、というもの。
for f in *.html; do /c/Users/${user}/local/emacs-26.3-x86_64/bin/emacs --batch $f --eval='(princ (dom-texts (dom-by-id (libxml-parse-html-region (point-min) (point-max)) "my-content") "\n"))' > $f.txt; done
- "/c/Users/${user}/local/emacs-26.3-x86_64/bin/emacs": Windows上のemacsコマンドのパス
- "--batch": Emacsバッチモード。バッチモードの定義は下記参考ページに書いてある。大雑把には、普段「バッファ」や「ウィンドウ」を使用するEmacsの入出力関数(message, princなど)を標準入力や標準出力、標準エラー出力に結び付けて、非インタラクティブに処理を実行する。
- "--batch"直後の$fは処理対象のhtmlファイルで、非インタラクティブなEmacsはこのファイルを開いてバッファに読み込む。
- "--eval"の引数としてelispコードを渡す。この例ではhtmlを開いたバッファ全体を"libxml-parse-html-region"関数に渡してDOM化し、次のそのDOMから"my-content"というidをもつ要素を"dom-by-id"関数で選び、選ばれた要素を"dom-texts"関数に渡してテキスト部分を抽出して"princ"で出力している。どの関数もEmacs標準のものだから外部のelispは利用していない。