生テキスト要素

生テキスト要素

[9] HTML 構文において、終了タグまでのすべての文字がそのままテキストとして解釈される要素のことを生テキスト要素 (raw text element) といいます。

仕様書

定義

[11] HTML 仕様によれば、生テキスト要素に分類されるのは次の2つの要素です >>10

[14] (構文の定義ではなく) 構文解析器の仕様上は次の各要素も同じように扱われます。

[15] script を除き、これらはいずれも共通生テキスト要素構文解析算法により処理されます。
[16] iframenoscript を除いた3つは廃止された要素であって不適合なので含まれていないのでしょう。 iframenoscriptHTML として解釈され得る文字列が内容モデルと規定されており、やや特殊な扱いになっているため、 ここでは含まれていないのでしょう (仕様書のコメントで、敢えて除外していると記述があります)。 (ただ文字参照の扱いや </iframe> 終了タグの適合性など、 HTML 仕様は少し抜けがあるように見えます。)

[25] script 要素については、 (HTML 構文としてではなく) script 要素自体においても内容の文字列としての構文が定義されています (>>24)。 この構文は HTML構文解析器で正しく構文解析される範囲に収まるようになっています。

[26] >>25 によれば script 要素内容として、 注釈のように見える文字列の中で script 開始タグ終了タグの組に見える文字列を使うことができ、 実際 HTML構文解析器によってそのような文字列は (タグではなく) 文字データとして処理されます。 しかし、生テキスト要素に共通して適用される HTML 構文の規定により、 script 要素内容として script 終了タグに見える文字列を使うことができず、したがって HTML 構文に適合するためにはこれを使うことができません。

[27] 例えば

<script>
  <!--
    document.write ('<script> alert (2) </script>');
  //-->
</script>

... は、 HTML構文解析器を通すと著者が意図した通りに解釈されます。そうして生成された DOM 自体は HTML 仕様に適合します。しかし、この HTML 片は HTML 構文に適合していません。

構文解析

[17] HTML構文解析算法においては、 共通生テキスト要素構文解析算法 (generic raw text element parsing algorithm) によって >>11>>14要素の構文解析の方法が規定 (>>12) されています。ただし script についてはスクリプトの実行があるので、別途規定されています。

[23] なお、 svg 要素math 要素の中では、 一部の統合点要素内を除き、 >>11>>14要素名要素SVGMathML要素として扱われ、通常の要素同様に構文解析されます。これらは生テキスト要素ではありません。

[28] 例えば、

<script>
  alert ('&amp;');
</script>
<svg>
  <script>
    alert ('&amp;');
  </script>
</svg>

... を表示すると「&amp;」と「&」が alert されます。また、

<script>
<!--
  alert ('&amp;');
//-->
</script>
<svg>
  <script>
  <!--
    alert ('&amp;');
  //-->
  </script>
</svg>

... を表示すると、「&amp;」とだけ alert されます。

歴史

HTML が SGML 応用と信じられていた時代

[1] HTML の太古の要素型である xmplisting は、開始タグ以後、 対応する終了タグ (xmp なら </xmp>listing なら </listing>) 以外のすべてのマーク認知しません。 このような要素内容マークの解釈に関する性質を HTML-CDATA と (勝手に) 呼んでいます。

[2] SGML要素内容マークの解釈の方法としての CDATA開始タグ以後ほとんどのマーク認知を中止しますが、 開始タグと同じ要素型名が入った終了タグでなくても (例えば空タグ </> であっても) そこで終わりとみなされます。ですから、 <xmp>... <em>aaa</em> ...</xmp>SGML 的には本来許されないのです。

[3] HTMLSGML 化にあたってこれが問題になり、 xmplisting は使わないことになりました。同じような要素型として pre が追加されましたが、 こちらは HTML-CDATA でも SGMLCDATA でもなく、普通の内容を持つものとして定義されました。

[4] ただし、 xmplisting後方互換性のために仕様から削除されずに残りました。 HTML 2.0 (RFC 1866 : IETF 提案標準 = 当時) では xmplisting は正式には SGMLCDATA として規定されていましたが、以前からの HTML-CDATA としての解釈も説明されていました。 (HTML 2.0SGML応用だったので、 SGML 違反を正式に規定するわけにはいきませんでした。)

xmplisting はその後 HTML 2.x (RFC 2070 : IETF 提案標準 = 当時) と HTML 3.2 (W3C 勧告) にもそのまま残りましたが、 HTML 4.0 (W3C 勧告) で完全に削除されました。

[5] 仕様上は >>4 のような状況でしたが、 Webブラウザの実装は元の HTML-CDATA のままでした。 xmplisting を使った文書pre の登場以後皆無といってよいのですが、 それ以前の文書との互換性のために現在でも SGML に基づく HTML の仕様は無視されています。

メモ: そろそろ思い切って削除してしまってもよさそうなものですが、 主要な Webブラウザで一度実装した要素型への対応を削除した例はほとんどありません。

[6] plaintext 要素型HTML-CDATA で実装されることがあります。この要素型タグは元々 HTML ではなく平文として以後解釈するべきことを示すもので、 当然終了タグは存在しませんでした。

もちろん SGML としても微妙な存在です。

それがいつのまにか、他の要素型と同じように終了タグ認知する Webブラウザが登場しました。しかしすべての Webブラウザがそれに追随したわけではありませんから、 終了タグ認知する Webブラウザとしない Webブラウザが混在しています。

[7] title 要素型も微妙な存在です。 title 要素型HTMLSGML によって定義されるようになる前から存在していました。 その時は実体参照文字参照もありませんでした。 そして title 内にマークを入れることなど考えられなかったので、 title開始タグ終了タグの間をそのまま題名として表示するように実装されていました。

SGML が意識されるようになって状況は徐々に変化していきました。 Webブラウザによって文字参照実体参照を解釈したり、 注釈宣言を解釈したりするようにもなりました。 空白の取扱いも他の要素型と同じようになっていきました。 開始タグ終了タグがあっても (他の文脈と同じように、未知のものとして) 無視するブラウザも出てきました。しかし、 このような変化は一斉に起こったものではなく、現在も実装間で統一されていません。

HTML5

[20] HTML5 によって HTMLSGML ではないと明確にされ、 独自の構文解析算法と構文の定義がなされました。その中でこれまで CDATA と呼ばれていた要素の種類には生テキスト要素という呼称が与えられました。

関連

[18] SGML では内容モデル CDATA が規定されており、 HTML生テキスト要素もそれに由来するようです。実際 HTMLSGML応用と信じられていた頃、生テキスト要素DTD 上で CDATA と定義されていました。 HTML生テキスト要素は当該要素終了タグ以外どんなテキスト内容として含めることができますが、 SGMLCDATA では終了タグとして認知され得る文字列を含めることは (現在開いている要素要素型名が異なっていたとしても) できないとされていました。

[19] HTML では類似した概念としてRCDATA要素があります。 こちらも生テキスト要素と同じようにタグを認識しませんが、文字参照は使うことができます。

[21] listing 要素は、かつては xmp 要素と同じように CDATA であるとされていましたが、 いつからか違った扱いをされるようになっており、現在の HTML構文解析算法では pre と同じように (ほとんど普通の要素として) 扱われています。 つまり、タグ文字参照も使うことができる要素になっています。

[22] plaintext 要素終了タグも含めてすべてのタグ文字参照を認識せずにテキストとみなします。 この要素適合しないため、特に分類名は与えられていません。

メモ

[29]

<{script|style}><!--/*--><!/**/
...
/*>*/</{script|style}>

If the fragment is parsed as an HTML element, the content is interpreted as raw text. Texts "<!--" and "/*...*/" are ignored as comments by CSS/JavaScript interpreter.

If the fragment is parsed as an SVG or MathML element in HTML document, the content is interpreted as foreign content, i.e. an HTML comment followed by a CDATA section, followed by text "*/". The content of CDATA section contains a CSS/JavaScript comment, the actual content, and "/*". Since the "/*" in the CDATA section is followed by "*/" after the CDATA section, they are interpreted as CSS/JavaScript comment.

Anyway, the content is interpreted literally, as far as it does not contain end tag, "]]>", or, in |script|, unpaired "<!--" or "-->".