HTML Tidy for HTML5 を yum でインストールする on CentOS7


<!-- 覗いちゃいやん😳 -->
<!-- でも覗いてくれてありがとう。長文だけど、ゆっくりしていってね！ -->

$\mathbb{この記事は、RedHat 系 OS に HTML5 対応の HTML Tidy を "yum␣install␣tidy" でインストールしたい人向けの記事です。}$

以下は、いずれも 2018/06/20 現在。

## TL;DR

「HTML Tidy」はインデントや構造が崩れた HTML/XML を修正して綺麗に整えてくれるプログラム。

```index.html
<div><p>hoge</div>
<p>fuga
<div>piyo</div>
```
↓ `$ tidy -o output.html -f errs.txt -utf8 -i index.html`

```output.html
<div>
  <p>hoge</p>
</div>

<p>fuga</p>
<div>
  piyo
</div>
```

**HTML Tidy は標準（`base`）リポジトリにはいない**ので、[`epel` リポジトリ](https://www.google.co.jp/search?q=site:qiita.com+EPEL+%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA+%E3%81%A8%E3%81%AF)を有効にすればインストールできる。

```bash
$ su -
$ yum install epel-release -y
$ yum --enablerepo=epel update -y
$ yum list | grep tidy
$ yum install tidy.x86_64
$ tidy --version
HTML Tidy for Linux version 5.4.0
```

### 概略

- XMLの構文も整えるため、わざと XML を崩してインジェクションするようなデータ対策にも効果的。
- 正式名称 `HTACG HTML Tidy`
- 「HTML Tidy」が HTML5 のサポートを始めたのは `v5.0.0` から。
- GitHub に引っ越してメンテナンス体制が再構築されたので、ここ [2〜3年で HTML5 対応に本腰になってきた](https://github.com/htacg/tidy-html5/graphs/contributors)。
- [最新版の「HTML Tidy」](https://github.com/htacg/tidy-html5/releases)は `HTML Tidy v5.6.0`（2018/06/20現在）
- `yum`, `rpm` ともにインストールできるのは１つ前の安定バージョンである `HTML Tidy v5.4.0`。
- 最新版バージョンの RPM パッケージは提供されていない。<br>そのため最新版をインストールしたい場合はやはりソースからビルドする必要がある。
- 「Tidy for HTML5？それって可愛いの？」という方は TS;DR をお読みください。

### 公式リンク

- [HTML Tidy 公式サイト](http://www.html-tidy.org/)（新生）
- [公式リポジトリ](https://github.com/htacg/tidy-html5) @ GitHub <sup>← Tidy ユーザーは☆してあげてください</sup>
- [最新リリース・ページ](https://github.com/htacg/tidy-html5/releases)
- [各 OS 用バイナリ・ダウンロード・ページ](http://binaries.html-tidy.org/)
- [メンテナ軍団 (HTACG) のサイト](http://www.htacg.org/)

### 動作確認

- OS： CentOS Linux release 7.4.1708 (Core)
- `yum`： v3.4.3
- さくらのVPS（KUSANAGI）


## TS;DR

### 探し物は何ですか？見つけにくいタグですか？

とあるクライアント様の自家製の社内 [CMS](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%86%E3%83%B3%E3%83%84%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0) で、データを投げては自動的に作成される **HTML5 のデータが汚い**のです。

`min` 化（`minimized`）されているという訳ではありません。出力される HTML のインデントはグチャグチャ、改行タグが `<br>` `<br />` 混在、平気で[二歩を踏む](https://qiitadon.com/@KEINOS/99674566412862567)、条件によって `<div>` `<pre>` `<h4>` `<td>` の閉じ忘れなどがある、といった具合です。どんな CMS なのか、中身は謎です。

しかし、今回の要件は「CMS のサーバ本体やプログラムをいじらずに表示速度を速くして欲しい。しかも安く」というものでした。猶予（予算）は１日です。

幸いにも、月に 10 件程度のアクセスのために半分遊んでいる「さくらの VPS」のアカウントがあるので、それを使っていいということでした。

そこで、プロクシ的に **CMS のサーバとクライアントの間にキャッシュ・サーバを入れる**ことにしました。

### Cacheで👌？ いいえ「Cash👌」が問題です

キャッシュの仕組みは至極シンプルです。

「リクエストされたクエリでそのまま CMS を叩き、CMS から取得した HTML をキャッシュして表示する。以降は同じ ID でリクエストされた場合はキャッシュを使う」という王道の手法です。ここまではサブドメインの切り替え含めて一時間程度で出来たのですが、後先を考えた上で余計なことをしたくなりました。

「**どうせキャッシュするなら綺麗に整形してからキャッシュしたいな**」と。

そうです。俗に言う「[ボケツフォール型開発](https://qiitadon.com/@scivola/100128108200725271)」です。

これは、私が綺麗好きだからというわけではありません。「表示が崩れた」と、かなりの頻度でチョイチョイ呼び出されるので、確認すると**ほぼ 100% システム側のタグの閉じ忘れが原因**だったからです。稀によくあるパターンだと思います。

そのたびに「CMS 本体を触れない以上、手の出しようがない」と説明するのが面倒なのですが、ブラウザによっては正常に表示されるため「CMS の問題ではない」と思い込んでいる人への説得が毎回面倒なのです。とても。

いや、説明自体はヤブサかではないのです。

問題は「本職の翻訳系エンジニアさんに依頼するのは費用が高すぎる」と、本業でもない**翻訳のアルバイトとして私は来ていること**です。

つまり「１本いくらの出向型の翻訳作業で、請求書のない領収書と現金のみの消費税なお仕事」なのです。作業の手が止まると、その間のお賃金は発生しません。

翻訳もプログラミングと同じで、作業が一旦中断されると頭を元に切り替えるのに意外に時間がかかります。そのため、肝心の翻訳作業も予定の半分くらいのペースになってしまっているのです。

少なくとも同じデータでは問題がおきないよう、対策として「入力データに手動で『閉じるタグ』を入れてもらう」のですが、「どこに入れればいいか、まで案内しないといけない」という、**CMS のせいにするだけでは済まない損な性格が災い**してしまいます。おそらく、この CMS も然るべき事情があり、このような仕様になったと思うからです。

いずれにしても、その案内をする際に HTML ソースを見ると可読性がとても悪く、案内するのが大変だったのです。このオファーを機に「どうせなら綺麗にしよう」と思ったのです。

実のところ懐事情が[菅井君の家族石](https://ja.wikipedia.org/wiki/%E8%8F%85%E4%BA%95%E5%90%9B%E3%81%A8%E5%AE%B6%E6%97%8F%E7%9F%B3)状態なので、気概のあるフリーランサーであれば、お客様に営業をかけて問題の HTML5 を吐き出す側（CMS 本体）をイジレればいいのですが。**諸事情で触りたくありません**。

出向タイプの[グロス](https://www.google.co.jp/search?q=%E3%82%B0%E3%83%AD%E3%82%B9+gross+nett+%E7%99%BA%E6%B3%A8+%E5%8F%97%E6%B3%A8+%E3%83%93%E3%82%B8%E3%83%8D%E3%82%B9%E7%94%A8%E8%AA%9E)の案件に、案件と関係のない作業を差し込んで来たり、「この翻訳で訴えられたら大変だよなー」と<ruby>薄<rt>うっ</rt>っすら</ruby>と「（自腹で翻訳をプロにチェックしてもらってよ）」と低料金下請けに忖度ハラスメントをかましてくるようなパワ腹が出ている社長さんの、前任の担当者や CMS の開発会社が蒸発しているような会社であることを考えると、お察しいただけるかと思います。まぁ、フリーランスあるあるだと思いますが [gross](https://eow.alc.co.jp/search?q=gross) で [grouse](https://eow.alc.co.jp/search?q=grouse) な話しをしてしまいました。

さて、閑話休題。ふぅ。

### Tidy とは？

「Tidy」とは英語で「きちんとした」「片付いている」「整然としている」という意味で、可愛いらしい「Teddy Bear」とは関係なく、むしろ「Tidy Gian」（[きれいなジャイアン](https://www.google.co.jp/search?q=%E3%81%8D%E3%82%8C%E3%81%84%E3%81%AA%E3%82%B8%E3%83%A3%E3%82%A4%E3%82%A2%E3%83%B3)）に近いです。

おふざけはこれくらいにして、つまり、「[`HTML Tidy`](https://ja.wikipedia.org/wiki/HTML_Tidy)」とは HTML を綺麗にするプログラム（ライブラリ）です。

先の、HTML の構文が間違っていたり、インデンティングが整っていない HTML データを修正・整形してくれます。HTML や XML の構造をわざと崩してハッキングするような手法にも効果的です。

HTML データの整形では、おそらく最も有名なのが [`HTML Tidy`](https://ja.wikipedia.org/wiki/HTML_Tidy) なのですが、[macOS に標準で入っている](https://qiita.com/KEINOS/items/c82ed038fee1a0b0792e#tidy-v15181)との情報を得たので、持ち込みの作業マシンの macOS HighSierra のターミナルから `tidy --version` を叩いてみると、確かに `tidy` は入っており 2006 年物のビンテージものでした。

```bash
$ tidy --version
HTML Tidy for Mac OS X released on 31 October 2006 - Apple Inc. build 15.18.1
````

### Tidy for HTML5

しかし、**古いバージョンだと、どうも HTML5 の整形がうまくいかない**らしく、使い物になりませんでした。

調べてみたところ、現在の HTML Tidy が HTML5 を本格的にサポートしはじめたのは [2015 年（v5.0.0）以降](https://stackoverflow.com/a/38423236/8367711)とのこと。10 年以上前の HTML 解析エンジンでは当然 HTML5 なんて解析できるはずはありません。

Mac であれば、以下のいずれかお好きなパターンでインストールできます。

#### HTML5 Tidy for Mac

- [Fink](https://ja.wikipedia.org/wiki/Fink): `$ fink install tidy`
- [Homebrew](https://ja.wikipedia.org/wiki/Homebrew_(%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0)): `$ brew install tidy-html5`
- [MacPorts](https://ja.wikipedia.org/wiki/MacPorts): `$ sudo port install tidy`

しかし、どうせ最新版をインストールするなら私の個人的な Mac の作業ローカル・マシンよりも、むしろ、先のキャッシュ・サーバー側に入れてしまおうと思いました。

Linux の場合、**通常はソースからビルドしたり、RPM パッケージからインストールしたりするのが王道**です。

問題は、私は「インストールにまで依存関係に悩みたくない人」になってしまったので「バージョンアップは `yum update` してね」と済ませたいのです。[インストロール怖い](https://qiitadon.com/@KEINOS/470311)。

しかし、ググっても `yum` でインストールする記事がほとんどありません。

Tidy のサイトやリポジトリっぽいのも２、３個あり、そもそも Wikipedia にあるプロジェクトページへのリンクが SourceForge で「引っ越しました」状態になっていたりと、全体的に情報がバラバラです。

「お前も最新の情報にしてやろうか！」と、蝋人形のように時間の止まった記事に Wikipedian の血が騒ぎました。それは、まるで勉強を始める前に部屋の片付けをするような勢いで情報収集を始めたのです。仕事しろ。

### 本家 Tidy と HTACG

そんな中、[英語版の Wikipedia](https://en.wikipedia.org/wiki/HTML_Tidy) は割と更新されており、また[本家のヒストリー](http://www.html-tidy.org/#homepage19700401history)にも、もう少し詳しい情報がありました。情報がバラバラになった経緯の概要は以下の通りです。

1. 「HTML Tidy」は、W3C のメンバーであり初期のHTML（HTML, XHTML, VRML など）の制定にも深く関わった[デーブ・ラゲット氏](https://en.wikipedia.org/wiki/Dave_Raggett)が始めた。
1. 2003 年に C 言語でライブラリ化されると共に SourceForge のコミュニティーに引き継がれた。
1. しかし、引き継がれつつも停滞していたので（適当に）Fork する人が出てくるようになった。
1. 業を煮やした W3C が 2011 年にリポジトリを [SourceForge](http://tidy.sourceforge.net/) から [GitHub](https://github.com/htacg/tidy-html5) にフォークした。
1. W3C のメンバーであるマイケル・スミス氏が 2012 年に改めて引き継ぎ、メインの[公式のホームページ](http://www.html-tidy.org/)も一新。
1. さらに体制も見直され、[HTACG](http://www.htacg.org/) （HTML Tidy Advocacy Community Group）という HTML Tidy の支持団体が発足した。 
1. その後、この HTACG が W3C 公認のメイン・メンテナになったことで、やっとメンテナンス体制が整った。（←いまここ）

というのがここ２〜３年（2018 年現在）の話であり、情報がバラバラになった原因のようです。つまり **HTML Tidy for HTML5 は過渡期に入ったばかり**ということです。

### 「お前が落としたいのは、この金の Tidy か？銀の Tidy か？」

しかし、[公式のバイナリ（コンパイル済み）一覧](http://binaries.html-tidy.org/)を見ると、macOS 用や Windows 用の最新バイナリはあるのですが、RedHat 系の RPM は１つ前の安定バージョンしかありませんでした。

「RPM かぁ・・・更新マニュアル書くの面倒くさそうだなぁ」と悩んでいたところ、サークルで使っているサーバには `$ yum list | grep tidy` で `rpm` と同じバージョンが出てくるではないですか！

違いを比べたところ、[`epel` リポジトリ](https://qiita.com/muniere/items/6c4923a070cbbd824f39)に RPM と同じバージョンの Tidy が入っていました。

```bash:yumで最新バージョンが出てきたサーバーの方の環境情報
$ # OS のバージョン確認
$ cat /etc/redhat-release 
CentOS Linux release 7.4.1708 (Core) 

$ # YUM のバージョン確認
$ yum --version
3.4.3
インストール: rpm-4.11.3-25.el7.x86_64 (日時: 2018-03-08 18:21)
  構築      : CentOS BuildSystem <http://bugs.centos.org>  (日時: 2017-08-03 03:48)
  コミット  : Panu Matilainen <pmatilai@redhat.com> (日時: 2017-03-17)

インストール: yum-3.4.3-154.el7.centos.1.noarch (日時: 2018-03-08 18:22)
  構築      : CentOS BuildSystem <http://bugs.centos.org>  (日時: 2018-01-30 13:51)
  コミット  : Johnny Hughes <johnny@centos.org> (日時: 2018-01-30)

インストール: yum-plugin-fastestmirror-1.1.31-42.el7.noarch (日時: 2018-03-08 18:22)
  構築      : CentOS BuildSystem <http://bugs.centos.org>  (日時: 2017-08-11 10:23)
  コミット  : Valentina Mukhamedzhanova <vmukhame@redhat.com> (日時: 2017-03-21)

$ # 登録済みの YUM リポジトリ一覧
$ yum repolist
読み込んだプラグイン:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: ftp.iij.ad.jp
 * epel: mirror.dmmlabs.jp
 * extras: ftp.iij.ad.jp
 * ius: hkg.mirror.rackspace.com
 * updates: ftp.iij.ad.jp
リポジトリー ID              リポジトリー名                                        状態
!base/7/x86_64               CentOS-7 - Base                                          9,591
!carlwgeorge-ripgrep/x86_64  Copr repo for ripgrep owned by carlwgeorge                 4+2
!epel/x86_64                 Extra Packages for Enterprise Linux 7 - x86_64        12,451+1
!extras/7/x86_64             CentOS-7 - Extras                                          448
!groonga/7/x86_64            Groonga for CentOS 7 - x86_64                            1,612
!ius/x86_64                  IUS Community Packages for Enterprise Linux 7 - x86_6      469
!kusanagi                    KUSANAGI RPM packages                                      179
!mariadb                     MariaDB                                                     32
!mondorescue                 centos 7 x86_64 - mondorescue Vanilla Packages           85+63
!updates/7/x86_64            CentOS-7 - Updates                                       2,416
!zabbix/x86_64               Zabbix Official Repository - x86_64                        235
!zabbix-non-supported/x86_64 Zabbix Official Repository non-supported - x86_64            4
repolist: 27,526

$ # インストール可能な Tidy パッケージの確認
$ yum list | grep tidy
compat-libtidy.x86_64                    0.99.0-37.20091203.el7         epel    
compat-libtidy-devel.x86_64              0.99.0-37.20091203.el7         epel    
jtidy.noarch                             2:1.0-0.16.20100930svn1125.el7 base    
jtidy-javadoc.noarch                     2:1.0-0.16.20100930svn1125.el7 base    
libtidy.x86_64                           5.4.0-1.el7                    epel    
libtidy-devel.x86_64                     5.4.0-1.el7                    epel    
libtidyp.x86_64                          1.02-11.el7                    epel    
libtidyp-devel.x86_64                    1.02-11.el7                    epel    
perltidy.noarch                          20121207-3.el7                 base    
php-horde-Horde-Text-Filter-Csstidy.noarch
php-tidy.x86_64                          5.4.16-7.el7                   epel    
php56u-tidy.x86_64                       5.6.34-1.ius.centos7           ius     
php70u-tidy.x86_64                       7.0.28-1.ius.centos7           ius     
php71u-tidy.x86_64                       7.1.15-1.ius.centos7           ius     
php72u-tidy.x86_64                       7.2.3-1.ius.centos7            ius     
tidy.x86_64                              5.4.0-1.el7                    epel  ⇦ いた
tidyp.x86_64                             1.02-11.el7                    epel    
```

なるほど。`epel` を有効にしてインストールすればいいのね、と問題のサーバーでも `epel` を有効にします。

```bash
$ sudo yum install epel-release -y
$ sudo yum --enablerepo=epel update -y
```

そして、`$ yum list | grep tidy` でインストール可能なパッケージを検索し、 "`tidy.x86_64`"が表示されることを確認してインストールします。

```bash
$ # tidy.x86_64 のインストール
$ sudo yum install tidy.x86_64
読み込んだプラグイン:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: ftp.iij.ad.jp
 * epel: mirror.dmmlabs.jp
 * extras: ftp.iij.ad.jp
 * ius: hkg.mirror.rackspace.com
 * updates: ftp.iij.ad.jp
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ tidy.x86_64 0:5.4.0-1.el7 を インストール
--> 依存性の処理をしています: libtidy(x86-64) = 5.4.0-1.el7 のパッケージ: tidy-5.4.0-1.el7.x86_64
--> トランザクションの確認を実行しています。
---> パッケージ libtidy.x86_64 0:5.4.0-1.el7 を インストール
--> 依存性解決を終了しました。

依存性を解決しました

==========================================================================================
 Package             アーキテクチャー   バージョン                 リポジトリー      容量
==========================================================================================
インストール中:
 tidy                x86_64             5.4.0-1.el7                epel             172 k
依存性関連でのインストールをします:
 libtidy             x86_64             5.4.0-1.el7                epel             174 k

トランザクションの要約
==========================================================================================
インストール  1 パッケージ (+1 個の依存関係のパッケージ)

総ダウンロード容量: 346 k
インストール容量: 1.3 M
Is this ok [y/d/N]: y
Downloading packages:
(1/2): libtidy-5.4.0-1.el7.x86_64.rpm                              | 174 kB  00:00:00     
(2/2): tidy-5.4.0-1.el7.x86_64.rpm                                 | 172 kB  00:00:00     
------------------------------------------------------------------------------------------
合計                                                      1.1 MB/s | 346 kB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  インストール中          : libtidy-5.4.0-1.el7.x86_64                                1/2 
  インストール中          : tidy-5.4.0-1.el7.x86_64                                   2/2 
  検証中               : tidy-5.4.0-1.el7.x86_64                                   1/2 
  検証中               : libtidy-5.4.0-1.el7.x86_64                                2/2 

インストール:
  tidy.x86_64 0:5.4.0-1.el7                                                               

依存性関連をインストールしました:
  libtidy.x86_64 0:5.4.0-1.el7                                                            

完了しました!

$ 
$ # インストールした tidy のバージョン確認
$ tidy --version
HTML Tidy for Linux version 5.4.0
```

あとは、お好きな言語で fetch して cache してね、という流れです。

Wikipedia も近いうちに編集したいですが、この苦労を吐き出したかったので先に Qiita に書きました。むしろポエムに近い記事なので TL;DR はブログに書けばよかったのかもしれませんが、勢いなので Qiita に載せます。

たかが数行のコマンドのために、ここまで読んでいただいてありがとうございます。お仕事もメンタルも、しっかりやっ Tidy と行きたいものです。日本のエンジニアに幸あれ。

## 参考文献

- [HTML Tidy 公式サイト](http://www.html-tidy.org/)
- [yumリポジトリ追加リスト 完全版](https://qiita.com/bezeklik/items/9766003c19f9664602fe) @ Qiita
- [HTML tidyをCentOSにインストールする](http://mk-55.hatenablog.com/entry/2017/11/19/152639) @ mk_55's diary
- [PHPで壊れたHTMLを整形する](https://qiita.com/mpyw/items/58c7aa797d7735469e3a) @ Qiita
- [【初心者でもわかる】yumコマンドの使い方とリポジトリの追加方法](https://eng-entrance.com/linux-package-yum) @ エンジニアの入り口
- [Tidy HTML5 & PHP7](https://stackoverflow.com/questions/42392262/tidy-html5-php7) @ StackOverflow