[インデックス 11368] ファイルの概要
このコミットは、Go言語の標準ライブラリにおけるHTMLパーサーのパッケージ構造に関する重要な変更を記録しています。具体的には、開発中のHTMLパーサーを html
パッケージから exp/html
パッケージへ移動させるものです。これは、Go 1のリリースに向けてAPIの安定性を確保するための戦略的な判断であり、パーサーのAPIがまだ確定していないため、実験的な位置付けとして exp
ディレクトリに配置されました。既存の html
パッケージは、EscapeString
と UnescapeString
の2つの関数のみを保持する形に変更されています。
コミット
- Author: Nigel Tao nigeltao@golang.org
- Date: Wed Jan 25 10:54:59 2012 +1100
- Commit Hash: 324513bc5f1aa44685e547fec5e04fd0b2c8af40
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/324513bc5f1aa44685e547fec5e04fd0b2c8af40
元コミット内容
html: move the HTML parser to an exp/html package. The parser is a
work in progress, and we are not ready to freeze its API for Go 1.
Package html still exists, containing just two functions: EscapeString
and UnescapeString.
Both the packages at exp/html and html are "package html". The former
is a superset of the latter.
At some point in the future, the exp/html code will move back into
html, once we have finalized the parser API.
R=rsc, dsymonds
CC=golang-dev
https://golang.org/cl/5571059
変更の背景
この変更の主な背景には、Go言語のバージョン1(Go 1)のリリースに向けたAPIの安定性への強いコミットメントがあります。Go 1は、Go言語の長期的な互換性を保証するための重要なマイルストーンとして位置づけられていました。一度Go 1の標準ライブラリに含まれたAPIは、将来のバージョンでも後方互換性が維持されることが約束されており、これはGoエコシステム全体の安定性と信頼性を築く上で極めて重要でした。
HTMLパーサーはウェブアプリケーション開発において非常に重要なコンポーネントですが、そのAPI設計は複雑であり、当時の開発段階ではまだ試行錯誤が続いていました。Goチームは、未成熟なAPIをGo 1の安定版に含めることで、将来的に互換性のない変更を余儀なくされるリスクを避けたいと考えました。
そこで、このコミットでは、HTMLパーサーを html
パッケージから exp/html
(experimental HTML) パッケージへと移動させるという決定がなされました。exp
ディレクトリは、Goの標準ライブラリにおいて、まだAPIが安定しておらず、将来的に変更される可能性がある実験的なパッケージを配置するための特別な場所です。これにより、開発者はパーサーの機能を試すことができますが、そのAPIがGo 1の互換性保証の対象外であることを明確に示しています。
前提知識の解説
- Go言語のパッケージシステム: Go言語は、コードのモジュール化と再利用のためにパッケージシステムを採用しています。各Goファイルは
package
宣言を持ち、関連する機能がまとめられています。パッケージはディレクトリ構造に対応し、import
文で他のパッケージの機能を利用できます。 - Go 1の互換性保証: Go 1は、Go言語の歴史において非常に重要なリリースでした。このリリース以降、Goチームは「Go 1の互換性保証 (Go 1 Compatibility Guarantee)」を掲げ、Go 1で公開されたAPIは、特別な理由がない限り、将来のGoのバージョンでも後方互換性が維持されることを約束しました。これにより、Goで書かれたプログラムが将来のGoバージョンでも動作し続けることが保証され、開発者は安心してライブラリやアプリケーションを構築できるようになりました。
exp
ディレクトリ: Goの標準ライブラリには、exp
という特別なディレクトリが存在します。このディレクトリに配置されたパッケージは「実験的 (experimental)」と見なされ、そのAPIはGo 1の互換性保証の対象外です。つまり、これらのパッケージのAPIは、将来のGoのバージョンで予告なく変更されたり、削除されたりする可能性があります。これは、新しいアイデアや機能が標準ライブラリに組み込まれる前に、コミュニティからのフィードバックを得つつ、API設計を洗練させるためのメカニズムとして機能します。- HTMLパーサー: HTMLパーサーは、HTMLドキュメントを読み込み、その構造を解析して、プログラムが扱えるデータ構造(通常はDOMツリー)に変換するソフトウェアコンポーネメントです。ウェブブラウザ、スクレイピングツール、HTMLテンプレートエンジンなど、様々なアプリケーションで利用されます。HTMLは非常に柔軟な(そして時に不完全な)構文を持つため、堅牢なHTMLパーサーを実装することは複雑な作業です。
- HTMLエンティティ: HTMLエンティティは、HTMLドキュメント内で特殊文字(例:
<
、>
、&
)や、キーボードから直接入力できない文字(例:©
、™
)を表現するための仕組みです。&
(&
)、<
(<
)、>
(>
)、"
("
)、'
('
)などの名前付きエンティティや、&#xNNNN;
(16進数)や&#NNNN;
(10進数)のような数値文字参照があります。
技術的詳細
このコミットの技術的な核心は、Goのパッケージ管理とAPIの進化戦略にあります。
-
パッケージの移動とリネーム:
src/pkg/html
ディレクトリにあったHTMLパーサー関連のファイル群が、src/pkg/exp/html
ディレクトリに移動されました。これは、ファイルパスの変更だけでなく、Goのビルドシステムにおけるパッケージの参照パスも変更されることを意味します。- コミットメッセージにある
src/pkg/{ => exp}/html/
という表記は、Gitの差分表示でディレクトリのリネームを示しています。 Makefile
の変更 (src/pkg/Makefile
とsrc/pkg/exp/html/Makefile
) は、新しいexp/html
パッケージがビルドシステムに認識されるようにするためのものです。
-
パッケージ名の重複と共存:
- 興味深いのは、移動後の
exp/html
パッケージも、元のhtml
パッケージも、どちらもpackage html
と宣言されている点です。これは、Goのパッケージ名がディレクトリ名と必ずしも一致する必要がないことを示しています(ただし、慣習的には一致させることが推奨されます)。 - これにより、
exp/html
パッケージはhtml
パッケージの「スーパーセット」として機能します。つまり、exp/html
をインポートするコードは、パーサー機能を含む完全なHTML処理機能を利用でき、一方、html
パッケージをインポートするコードは、EscapeString
とUnescapeString
の基本的な文字列エスケープ機能のみを利用できます。
- 興味深いのは、移動後の
-
APIの段階的導入:
- この戦略は、Go 1のリリース前に、まだAPIが固まっていない機能を標準ライブラリに含めるための一般的なパターンでした。
exp
ディレクトリに置くことで、GoチームはAPIを自由に反復・改善でき、ユーザーは不安定なAPIに依存することなく、安定したGo 1のリリースを待つことができます。 - コミットメッセージにある「At some point in the future, the exp/html code will move back into html, once we have finalized the parser API.」という記述は、将来的にパーサーAPIが安定したと判断された場合、
exp/html
の内容が再びhtml
パッケージに統合される計画があることを示しています。これは、Goの標準ライブラリがどのように進化していくかを示す良い例です。
- この戦略は、Go 1のリリース前に、まだAPIが固まっていない機能を標準ライブラリに含めるための一般的なパターンでした。
-
entity.go
の追加:src/pkg/exp/html/entity.go
は、このコミットで新規追加されたファイルの中で最も大きなものです。このファイルは、HTML5で定義されている膨大な数の名前付き文字参照(HTMLエンティティ)とその対応するUnicodeルーン(文字)のマッピングを定義しています。- HTMLパーサーが正しく機能するためには、
&
や©
のようなエンティティを対応する文字に変換する機能が不可欠です。このファイルは、その変換ロジックの基盤となるデータを提供します。
コアとなるコードの変更箇所
このコミットにおけるコアとなるコードの変更は、主に以下のファイル移動と新規ファイルの追加です。
src/pkg/Makefile
:exp/html
が新しいディレクトリとしてDIRS
リストに追加され、ビルドシステムがこの新しい実験的パッケージを認識するように変更されました。
src/pkg/exp/html/Makefile
(新規):exp/html
パッケージのビルド設定ファイルが新規作成されました。このファイルは、パッケージ名 (TARG=html
) と、このパッケージに含まれるGoソースファイル (GOFILES
) のリストを定義しています。
src/pkg/{ => exp}/html/const.go
など多数のファイル (リネーム):src/pkg/html/
ディレクトリにあった既存のHTMLパーサー関連のGoソースファイル(const.go
,doc.go
,doctype.go
,foreign.go
,node.go
,parse.go
,render.go
,token.go
および関連するテストファイルやテストデータ)が、src/pkg/exp/html/
ディレクトリに移動されました。Gitの差分ではsimilarity index 100%
と表示されており、ファイルの内容自体は変更されていないことを示します。
src/pkg/exp/html/entity.go
(新規):- HTMLエンティティとUnicodeルーンのマッピングを定義する、非常に大きなファイルが新規追加されました。
src/pkg/exp/html/entity_test.go
(新規):entity.go
で定義されたエンティティマッピングのテストファイルが新規追加されました。
src/pkg/exp/html/escape.go
(新規):- HTMLエスケープ/アンエスケープ処理を実装するファイルが新規追加されました。
src/pkg/html/Makefile
(変更):- 元の
html
パッケージのMakefile
から、パーサー関連のファイルが削除されました。
- 元の
src/pkg/html/escape.go
(変更):- 元の
html
パッケージのescape.go
が変更され、EscapeString
とUnescapeString
の2つの関数のみが残るように簡素化されました。
- 元の
コアとなるコードの解説
このコミットの主要なコード変更は、HTMLパーサーの機能が exp/html
に移管されたこと、そして entity.go
と escape.go
という重要な新しいファイルが導入されたことです。
-
exp/html/entity.go
:- このファイルは、HTMLパーサーがHTMLエンティティを正しく解釈するために不可欠なデータを提供します。
- 内部的には、
entity
というmap[string]rune
型の変数(Goのマップ型)が定義されており、キーにはHTMLエンティティ名(例:"amp;"
、"nbsp;"
)、値にはそれに対応するUnicodeのルーン(文字コード)が格納されています。 - 例えば、
"amp;"
は'\U00000026'
(Unicodeの&
文字) に、"COPY;"
は'\U000000A9'
(Unicodeの©
文字) にマッピングされています。 - このマップは、HTML5の仕様に準拠した広範なエンティティリストを含んでおり、パーサーがHTMLドキュメント内のエンティティを効率的に実際の文字に変換できるようにします。
-
exp/html/escape.go
:- このファイルは、HTMLの特殊文字をエスケープ(例:
<
を<
に変換)したり、エスケープされた文字をアンエスケープ(例:>
を>
に変換)したりする機能を提供します。 - HTMLコンテンツを安全にウェブページに表示したり、ユーザー入力からHTMLタグを無効化したりする際に不可欠な機能です。
- 元の
html
パッケージにもEscapeString
とUnescapeString
が残されていますが、exp/html
のescape.go
はパーサー内部でより詳細な制御や、将来的な拡張性を考慮した実装を含んでいる可能性があります。
- このファイルは、HTMLの特殊文字をエスケープ(例:
-
パーサーのコアロジック (
parse.go
,token.go
,render.go
など):- これらのファイルは、HTMLドキュメントの字句解析(トークン化)、構文解析(DOMツリー構築)、そしてDOMツリーからHTML文字列へのレンダリングといった、HTMLパーサーの主要な機能を実装しています。
exp
ディレクトリへの移動により、これらのAPIはGo 1の安定版とは別に、継続的に開発・改善されることになりました。
この変更により、Go言語のHTML処理機能は、APIの安定性を損なうことなく、より堅牢で機能豊富なパーサーへと進化するための道筋がつけられました。
関連リンク
- Go Code Review: https://golang.org/cl/5571059
参考にした情報源リンク
- Go 1 Compatibility Guarantee: https://go.dev/doc/go1compat (Go 1の互換性保証に関する公式ドキュメント)
- Go
exp
packages: https://go.dev/doc/go-project-structure#exp (Goプロジェクト構造におけるexp
ディレクトリの説明) - HTML Living Standard - Named character references: https://html.spec.whatwg.org/multipage/named-character-references.html (HTML5における名前付き文字参照の定義)
- HTML Living Standard - Parsing HTML documents: https://html.spec.whatwg.org/multipage/parsing.html (HTMLドキュメントの解析に関する仕様)