[インデックス 13356] ファイルの概要
このコミットは、Go言語の実験的なHTMLパーサーライブラリ exp/html
内の atom
パッケージに、いくつかの新しいHTMLアトム(要素名や属性名)を追加するものです。具体的には、src/pkg/exp/html/atom/gen.go
、src/pkg/exp/html/atom/table.go
、src/pkg/exp/html/atom/table_test.go
の3つのファイルが変更されています。
コミット
commit 834edc4257b45176d8bbacc4d612a43372f9556b
Author: Nigel Tao <nigeltao@golang.org>
Date: Fri Jun 15 15:39:25 2012 +1000
exp/html/atom: add some more atoms.
R=r, dsymonds
CC=golang-dev
https://golang.org/cl/6298085
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/834edc4257b45176d8bbacc4d612a43372f9556b
元コミット内容
このコミットの目的は、exp/html/atom
パッケージにさらにいくつかのHTMLアトムを追加することです。これにより、HTMLパーサーがより多くのHTML要素や属性を認識し、効率的に処理できるようになります。
変更の背景
Go言語の exp/html
パッケージは、HTML5の仕様に準拠した堅牢なHTMLパーサーを提供することを目指していました。このパーサーは、HTMLドキュメントを解析し、DOMツリーを構築するために使用されます。HTMLの要素名や属性名は非常に多岐にわたるため、これらを効率的に扱うためのメカニズムが必要です。
exp/html/atom
パッケージは、HTMLの要素名や属性名を数値ID(アトム)にマッピングすることで、文字列比較のオーバーヘッドを削減し、パーサーのパフォーマンスを向上させる役割を担っています。新しいHTML要素や属性が標準化されたり、広く使われるようになったりするにつれて、それらを atom
パッケージに追加していく必要がありました。
このコミットは、当時まだ実験的であった exp/html
パッケージが、より多くのHTML構造を正確に解析できるようにするための継続的な改善の一環として行われました。特に、blink
、prompt
、public
、spacer
、system
といった、HTMLの歴史の中で登場した、あるいは特定の文脈で使われる可能性のある要素や属性が追加されています。
前提知識の解説
Go言語の exp/html
パッケージ
exp/html
は、Go言語の標準ライブラリ html
パッケージの前身、または実験的なバージョンとして開発されていたパッケージです。HTML5の仕様に基づいて、HTMLドキュメントを解析し、DOM(Document Object Model)ツリーを生成する機能を提供します。このパッケージは、ウェブスクレイピング、HTMLテンプレートの処理、HTMLコンテンツの検証など、様々な用途で利用されます。
HTMLアトム (Atom)
HTMLパーサーにおいて、「アトム」とは、HTMLの要素名(例: div
, p
, a
)や属性名(例: href
, class
, id
)を、内部的に一意の数値IDにマッピングしたものです。これにより、文字列としてこれらの名前を扱う代わりに、数値IDとして扱うことができます。
アトム化の主な利点は以下の通りです。
- パフォーマンスの向上: 文字列の比較は計算コストが高い操作ですが、数値の比較は非常に高速です。HTMLドキュメントの解析では、要素名や属性名の比較が頻繁に行われるため、アトム化によってパーサーの処理速度が大幅に向上します。
- メモリ使用量の削減: 同じ要素名や属性名がドキュメント内で何度も出現する場合でも、メモリ上にはその文字列が一度だけ格納され、それ以降は数値IDが参照されるため、メモリ使用量を削減できます。
- コードの簡潔化: 特定の要素や属性を識別する際に、文字列リテラルではなく、定義済みのアトム定数を使用することで、コードの可読性が向上し、タイプミスによるバグを防ぐことができます。
exp/html/atom
パッケージは、これらのアトムを管理し、文字列と数値ID間の変換機能を提供します。
gen.go
と table.go
の役割
gen.go
: このファイルは、HTMLアトムのリストを定義するために使用されます。通常、このファイルは手動で編集されるのではなく、アトムのリストを元にtable.go
のような他のファイルを自動生成するためのスクリプトやツールによって利用されます。extra
変数には、標準的なHTML5の要素や属性以外に、パーサーが認識すべき追加のアトムが文字列スライスとして定義されています。table.go
: このファイルは、gen.go
の情報に基づいて自動生成されることが想定されています。HTMLアトムの文字列と数値IDのマッピング、およびその逆のマッピング(数値IDから文字列への変換)を効率的に行うためのデータ構造(ハッシュテーブルや配列など)が定義されています。このファイルには、各アトムに対応するAtom
型の定数と、アトムのルックアップテーブルが含まれています。
table_test.go
の役割
table_test.go
: このファイルは、table.go
で定義されたアトムのルックアップテーブルが正しく機能するかどうかを検証するための単体テストが含まれています。アトムの文字列から数値IDへの変換、および数値IDから文字列への変換が期待通りに行われることを確認します。新しいアトムが追加された場合、それらが正しく認識されることを保証するために、テストケースも更新される必要があります。
技術的詳細
このコミットでは、主に以下の技術的変更が行われています。
-
gen.go
のextra
スライスへの追加:extra
スライスは、HTMLパーサーが認識すべき追加の要素名や属性名を文字列として保持しています。このコミットでは、"blink"
、"prompt"
、"public"
、"spacer"
、"system"
の5つの文字列がこのスライスに追加されました。これらの要素は、HTMLの歴史の中で存在したり、特定のブラウザでサポートされたり、あるいはXML/SVGなどの関連技術で使われたりする可能性のあるものです。blink
: Netscape Navigatorでサポートされていた非標準の要素で、テキストを点滅させる効果がありました。prompt
: HTML4以前のフォーム要素で、ユーザー入力のプロンプトを表示するために使われました。HTML5では非推奨です。public
: XMLやSGMLのDTD(Document Type Definition)で使われるPUBLIC識別子に関連する可能性があります。spacer
: Netscape Navigatorでサポートされていた非標準の要素で、空白スペースを挿入するために使われました。system
: SVGやXMLの文脈で、システム関連の識別子として使われる可能性があります。
-
table.go
のAtom
定数とルックアップテーブルの更新:gen.go
のextra
スライスに新しいアトムが追加されたことに伴い、table.go
が再生成(または手動で更新)され、これらの新しいアトムに対応するAtom
型の定数が追加されました。また、アトムの文字列と数値IDのマッピングを管理する内部ルックアップテーブル(table
配列とatomText
文字列)も更新されています。Atom
定数の値は、通常、アトムの文字列がatomText
内で始まるオフセットと、その文字列の長さの組み合わせでエンコードされます。例えば、Atom = 0xNNNLL
の形式で、NNN
がオフセット、LL
が長さを示すといった内部的な規則があります。このコミットでは、既存のアトムのオフセットも多数変更されており、これは新しいアトムの挿入によってatomText
文字列のレイアウトが再構築されたためと考えられます。 -
table_test.go
のtestAtomList
スライスへの追加: 新しいアトムが正しく認識され、アトム化されることを検証するために、testAtomList
スライスにも"blink"
、"prompt"
、"public"
、"spacer"
、"system"
が追加されました。これにより、テストスイートがこれらの新しいアトムの正確な処理を保証します。
これらの変更は、exp/html
パーサーがより広範なHTMLコンテンツを正確に解析できるようにするための、データ層の拡張に相当します。
コアとなるコードの変更箇所
src/pkg/exp/html/atom/gen.go
--- a/src/pkg/exp/html/atom/gen.go
+++ b/src/pkg/exp/html/atom/gen.go
@@ -599,6 +599,7 @@ var extra = []string{\n \"basefont\",\n \"bgsound\",\n \"big\",\n+\t\"blink\",\n \"center\",\n \"color\",\n \"desc\",\n@@ -624,8 +625,12 @@ var extra = []string{\n \"noembed\",\n \"noframes\",\n \"plaintext\",\n+\t\"prompt\",\n+\t\"public\",\n+\t\"spacer\",\n \"strike\",\n \"svg\",\n+\t\"system\",\n \"tt\",\n \"xmp\",\n }\n```
### `src/pkg/exp/html/atom/table.go`
このファイルは非常に多くの変更がありますが、主要な変更は新しい `Atom` 定数の追加と、既存の定数の値(オフセットと長さのエンコード)の再計算です。
例:
- `Blink Atom = 0x14705` (新規追加)
- `Prompt Atom = 0x5bf06` (新規追加)
- `Public Atom = 0x42706` (新規追加)
- `Spacer Atom = 0x30006` (新規追加)
- `System Atom = 0x5ed06` (新規追加)
また、`atomText` 文字列も新しいアトムを含むように再構築されています。
### `src/pkg/exp/html/atom/table_test.go`
```diff
--- a/src/pkg/exp/html/atom/table_test.go
+++ b/src/pkg/exp/html/atom/table_test.go
@@ -30,6 +30,7 @@ var testAtomList = []string{\n \"bdo\",\n \"bgsound\",\n \"big\",\n+\t\"blink\",\n \"blockquote\",\n \"body\",\n \"border\",
@@ -263,6 +264,8 @@ var testAtomList = []string{\n \"pre\",\n \"preload\",\n \"progress\",\n+\t\"prompt\",\n+\t\"public\",\n \"q\",\n \"radiogroup\",\n \"readonly\",
@@ -289,6 +292,7 @@ var testAtomList = []string{\n \"sizes\",\n \"small\",\n \"source\",\n+\t\"spacer\",\n \"span\",\n \"span\",\n \"spellcheck\",
@@ -305,6 +309,7 @@ var testAtomList = []string{\n \"summary\",\n \"sup\",\n \"svg\",\n+\t\"system\",\n \"tabindex\",\n \"table\",\n \"target\",
コアとなるコードの解説
このコミットの核心は、HTMLパーサーが認識できる「語彙」を拡張することにあります。
gen.go
の変更:extra
スライスに新しい文字列を追加することは、Goのexp/html
パッケージが将来的にサポートすべき、あるいは認識すべきHTML要素/属性の候補を明示的に指定する行為です。これは、パーサーの「知識ベース」を更新する第一歩となります。table.go
の変更: このファイルは、exp/html
パッケージのパフォーマンスの鍵となる部分です。新しいアトムが追加されると、table.go
内のデータ構造が再構築されます。具体的には、Atom
定数の数値IDが更新され、atomText
という巨大な文字列(すべてのアトム文字列を連結したもの)と、table
というハッシュテーブル(またはルックアップ配列)が再生成されます。この再生成は、新しいアトムが既存のアトムの間に挿入されることで、既存のアトムのオフセットがずれるため、広範囲にわたる変更となります。これにより、文字列比較ではなく数値比較で高速にアトムを識別できるようになります。table_test.go
の変更:testAtomList
に新しいアトムを追加することは、これらのアトムがパーサーによって正しくアトム化され、その逆の変換も正しく行われることを保証するためのテストカバレッジを確保します。これは、変更がライブラリの安定性と正確性を損なわないことを確認するために不可欠です。
全体として、このコミットは、GoのHTMLパーサーがより多くのHTML構造を効率的かつ正確に処理できるようにするための、基盤となるデータ構造の更新とテストの追加を行っています。
関連リンク
- Go言語の
html
パッケージ (現在の標準ライブラリ): https://pkg.go.dev/golang.org/x/net/html - Go言語の
x/net/html/atom
パッケージ: https://pkg.go.dev/golang.org/x/net/html/atom
参考にした情報源リンク
- Go言語のコミット履歴 (GitHub): https://github.com/golang/go/commits/master
- HTML5仕様 (W3C): https://www.w3.org/TR/html5/
- HTML要素リファレンス (MDN Web Docs): https://developer.mozilla.org/ja/docs/Web/HTML/Element
- HTML属性リファレンス (MDN Web Docs): https://developer.mozilla.org/ja/docs/Web/HTML/Attributes
- Go Code Review Comments (CL 6298085): https://golang.org/cl/6298085 (コミットメッセージに記載されているCLリンク)
- Go言語の
exp
パッケージの歴史に関する情報 (Stack Overflow, フォーラムなど) - アトム化 (コンピュータサイエンスの概念): 一般的な文字列処理の最適化手法に関する情報