[39] [DFN[[CODE[CDATA]]]] は、[DFN[[RUBYB[文字データ]@en[character data]]]]です。

* SGML

[40] 
[CODE(ABNF)[[DFN[文字データ]] := *[[データ文字]] ;; [[JISX4151]]‐1992 (47)]]

* HTML 4 の場合


** 属性値の型としての CDATA

[5] HTML 4 仕様書には [CODE(SGML)[CDATA]] の取り扱いについての言及がありますが、
完全な定義は [[ISO8879]] を参照し、その要約を示すにとどめるとしています。
(<http://www.w3.org/TR/html4/types.html#type-cdata> 参照。)

[6] HTML 4 [[利用者エージェント]]が行うべき
(should) [CODE(SGML)[CDATA]]
属性値(表記)の解釈は :
[WEAK[(cf. SGML の規定 : [CODE(WikiPage)[[[SGML//空白]]]])]]

= [[文字実体]]を文字に置換
= [[改行]] ([[LF]]) を無視
= [[復帰]] ([[CR]]) と[[タブ]]を1つの[[間隔]]に置換

Must ではなく should なのは、旧来の応用の救済でしょう。
SGML 的には必ずこう正規化しないといけないはずです。
更に、文字実体のみならず[[文字参照]]も文字に置換してもらわないと困ります。

[7] HTML 4 利用者エージェントは、更に最初と最後の空白を無視しても構いません
(may)。
たとえば [SAMP(HTML)[  myval  ]] は [SAMP(HTML)[myval]]
としても構いません。

しかし、[[著者]]はそのような値を使うべきではありません
(should not)。

この規定は旧来の UA・文書を救済するためのものでしょう。
SGML 的にはこのような扱いはありません。
[WEAK[(SGML 的な属性値を更にどう解釈するかという問題ですから、 SGML 違反ではありません。)]]

HTML 4 の規定では無視していいのは [CODE[white space]]
(単数) ですが、実際に仕様書に挙げられている例では最初と最後に複数個の空白があって無視されています。。。

[8] 利用者エージェントの中には連続する空白を1つの間隔にまとめてしまうものがありますが、
そういう話は特に書かれていません。
これについての救済はなしですか。そうですか。別に構いませんが。

[9] なお、 [[DTD]] 的に [CODE(SGML)[CDATA]]
であっても、 DTD で表現できない更なる制限があることもあります。

[[#comment]]


*** スクリプト・マクロ

[13] [[HTML 4]] は、 [CODE(SGML)[CDATA]] 
型属性で[DFN[[RUBYB[スクリプト・マクロ] [script macro]]]]のための構文を予約しています。

この機能は元々 [ABBR[[[NN4]]] [[[Netscape Navigator]] ([[Netscape Communicator]]) 4]] 
が実装していたもので、他の [ABBR[UA] [利用者エージェント]]
は実装していなかったので HTML 4 で標準機能として取入れるには至らなかったのだと思われます。

[14] 仕様書:
- [[HTML 4]]
-- [CITE[B.7.1 Reserved syntax for future script macros]]
<IW:HTML4:"appendix/notes.html#idx-script-1">

[15] '''適用対象''': この構文が予約されているのは、
[ABBR[HTML] [Hypertext Markup Language]] の 
[ABBR[[CODE(SGML)[CDATA]]] [character data]] 属性です。仕様書の例から、
[ABBR[[[DTD]]] [Document Type Definition]] 
の[[属性定義]]に[RUBY[直] [じか]]に 
[ABBR[[CODE(SGML)[CDATA]]] [character data]] 
と書かれている属性に限らず、 [SAMP(SGML)[%[[Color]]]]
のように[[引数実体参照]]を介して間接的に
[ABBR[[CODE(SGML)[CDATA]]] [character data]] 
であるものも含まれるようです。

[16] '''構文''': 属性値内の [SAMP(HTML)[&{[VAR[マクロ本体]]};]]
と書かれた部分がスクリプト・マクロとみなされます。

[17] '''意味''': HTML 4 仕様書は[Q[[RUBYB[現在の慣習] [current practice]]]]として次のように説明しています
[SRC[HTMl 4 B.7.1.1]]。

- [VAR[マクロ本体]]は[[既定スクリプト言語]]
[WEAK[([CODE(HTTP)[[[Content-Script-Type]]]] を参照してください。)]]
による1つ以上の[RUBYB[[[文]]] [[[statement]]]]です。
- 末尾の [CODE(char)[[[SEMICOLON]]]] は常に必要です。
[CODE(char)[SEMICOLON]] が続かない [CODE(char)[}]]
はマクロ本体の一部とみなします。
- スクリプト・マクロを含む属性は常に引用符が必要です。
[WEAK[([ABBR[SGML] [Standard Generalized Markup Language]] 的に言えば、[CODE(ABNF)[[[属性値]]]]ではなく[CODE(ABNF)[[[属性値表記]]]]で記述しなければなりません。)]]
- [ABBR[CDATA] [character data]] 属性は次のように処理します。
== [ABBR[SGML] [Standard Generalized Markup Language]]
[[構文解析器]]が [ABBR[SGML] [Standard Generalized Markup Language]]
[[実体参照]]を評価します。
== [[スクリプト機関]]がスクリプト・マクロを評価します。
== 評価結果の文字列を以後の処理に使います。
- スクリプト・マクロの処理は文書(再)読込み時に行います。
表示する大きさを変更した時や再描画時には行いません。

[23] HTML 4 仕様書には [SAMP(HTML)[&{[VAR[...]]};]]
の例しか出てきませんが、スクリプト・マクロの評価は SGML
的評価の後ですから、属性値表記に [SAMP(HTML)[&amp;{[VAR[...]]};]]
と書いてあっても同じことのはずです。

困ったことに、 [WEAK[(稀でしょうが)]] [Q[&{[VAR[...]]};]]
と属性値に書きたい時に、スクリプトを使わずに実現する方法がありません。
[SAMP(char)[{]] を SGML の[[文字参照]]で書いたとしても、
スクリプト・マクロが評価されるのは SGML 
的に解釈した後ですから意味がありません。
[[JavaScript]] なら [SAMP(HTML)[&{'&{[VAR[...]]}' + ';'};]]
とでも書けば良いのでしょうが、 JavaScript 対応の
[ABBR[UA] [利用者エージェント]]にしか意味が通じないことになります。

[24] スクリプト・マクロの中で [Q[};]] 
という文字列が使えるのかどうかは明記されていませんが、
おそらく駄目でしょう 
[WEAK[(入れ子の括弧等をチェックしながら構文解析なんてやってられないもん)]]。
>>23 の例のように適宜工夫する必要があります。

[27]
>>23 [[NC]] 4.8 で試してみましたが、 [SAMP(HTML)[&amp;{]] には対応していないようです。
([[名無しさん]])

[28]
で、 NC 4.8 は予想通り、 [CODE(SGML)[CDATA]] だろうが [CODE(SGML)[[[NUMBER]]]] だろうが [CODE(SGML)[[[ID]]]] だろうが構わずスクリプトを実行するようです。
([[名無しさん]])

[29]
あと、[CODE(ABNF)[属性値]]でも構わず実行しちゃってくれます。
([[名無しさん]])

[30]
<http://suika.fam.cx/~wakaba/-temp/test/html/script/macro/>
([[名無しさん]])

[31]
この機能、構文は記号だし、名前は一般的過ぎるし、検索しても全然意味がある情報が出てきませんよ。。。
([[名無しさん]])

[32]
>>31 [Q[マイナーだし]]も追加しとくか(w
([[名無しさん]] [WEAK[2004-12-12 07:00:29 +00:00]])

[33]
[CITE[FAQTs - Knowledge Base - View Entry - Which browsers support JavaScript entities?]] <http://www.faqts.com/knowledge_base/view.phtml/aid/1378/fid/126>
([[名無しさん]])

[34]
元々 [Q[[[JavaScript entity]]]] という名前らしい。結構情報が出てくる。

NN3 以上が実装しているらしい。
([[名無しさん]])

[35]
[CITE[JavaScript Entities]] <http://javascriptkit.com/javatutors/entity.shtml>
([[名無しさん]])

[36]
[CITE[[Chapter 10] 10.5 JavaScript Entities]] <http://www.chinalinuxpub.com/doc/oreillybookself/web/jscript/ch10_05.htm>

[CITE[Professional JavaScript]] <http://www.webreference.com/programming/javascript/professional/chap4/2/>

[CITE[[Appendix E] E.2 Client-side JavaScript]] <http://www.unix.org.ua/orelly/web/jscript/appe_02.html>

実は注釈宣言内でも使えるらしい (WinIE のあれと発想は同じ)。

([[名無しさん]])

[[#comment]]


**** 他との関係

[25] [[XSLT]] の [[HTML出力方式]]では、
[SAMP(HTML)[&amp;{[VAR[...]]};]] と出力されるはずの時に
[SAMP(HTML)[&{[VAR[...]]};]] に置き換えて出力するべきであるとされています
[SRC[XSLT 1.0 16.2]]。
ただし、 [ABBR[[CODE(SGML)[CDATA]]] [character data]]
属性に限るとの注釈がありません
[WEAK[(それどころか [SAMP(HTML)[};]] の存在も確認しなくて良いっぽいです)]] 
から、どの属性でもそうなのでしょうか。
[WEAK[([ABBR[SGML] [Standard Generalized Markup Language]] 的には無問題。)]]

[26] [ABBR[[[DOM]]] [Document Object Model]]
との関係は不明です。 [ABBR[DOM] [Document Object Model]]
では基本的に構文解析後の文書木を扱うことになっていますから、
スクリプト・マクロを処理した後の木を操作することになるのだと思われます。
[WEAK[(しかし、現実にはほとんどすべての [ABBR[UA] [利用者エージェント]] がスクリプト・マクロに対応していないので、そのまま属性値となってしまうのでしょうが。。。)]]

[37]
[CITE[Possible problem generating javascript entities with XSL from Jim Palmer on 1999-07-01 (xsl-editors@w3.org from July to September 1999)]] <http://lists.w3.org/Archives/Public/xsl-editors/1999JulSep/0000.html>

この指摘で XSLT 1.0 があーいう仕様になったらしい。
([[名無しさん]])

[[#comment]]


**** 例

[18] 文書の背景色を無作為に決定する [[JavaScript]] の例 ('''非推奨''')
[SRC[HTML 4 B.7.1.1]]
[PRE(HTML)[
<BODY bgcolor='&{randomrgb};'>
]PRE]

[19] 文書の背景色を時刻により決定する JavaScript の例 ('''非推奨''')
[SRC[HTML 4 B.7.1.1]]
[PRE(HTML)[
<BODY bgcolor='&{if(Date.getHours > 18)[VAR[...]]};'>
]PRE]

[20] [[クライアント側画像写像]]の座標やリンク先を
JavaScript で決定する例 ('''非推奨''')
[SRC[HTML 4 B.7.1.1]]
[PRE(HTML)[
<MAP NAME=foo>
   <AREA shape="rect" coords="&{myrect(imageuri)};" href="&{myuri};" alt="">
 </MAP>
]PRE]

[21] 画像の大きさを文書の特性により決定する例 ('''非推奨''')
[SRC[HTML 4 B.7.1.1]]
[PRE(HTML)[
<IMG src="bar.gif" width='&{document.banner.width/2};' height='50%' alt="banner">
]PRE]

[22] 画像やリンク先をスクリプトで決定する例 ('''非推奨''')
[SRC[HTML 4 B.7.1.1]]
[PRE(HTML)[
 <SCRIPT type="text/javascript">
   function manufacturer(widget) {
       ...
   }
   function location(manufacturer) {
       ...
   }
   function logo(manufacturer) {
       ...
   }
 </SCRIPT>
  <A href='&{location(manufacturer("widget"))};'>widget</A>
  <IMG src='&{logo(manufacturer("widget"))};' alt="logo">
]PRE]

この例では[[アポストロフィ]]を使っていますが、
二重引用符を使って
[PRE(HTML)[
<IMG src="&{logo(manufacturer(&quot;widget&quot;))};" alt="logo">
]PRE]

と等価に書き直すことができます。

[[#comment]]


** 要素の内容としての CDATA

[10] 要素の内容の型が [CODE(SGML)[CDATA]]
である場合、すなわち [CODE(HTMLe)[[[style]]]] 要素と
[CODE(HTMLe)[[[script]]]] 要素では、
[[タグ]]で囲まれた文字列がそのまま要素の内容の文字列として解釈されます。

ただし、文字列 [CODE(HTML)[</]] は [CODE(SGML)[[[etago]]]]
になってしまうので、書くことができません。
そこで当該要素は終わりになります。([[妥当]]であるなら、
それは正しい[[終了タグ]]になっているはずです。)

・・・というような感じのことが仕様書には書いてありますが、
実際には SGML 的には [CODE(SGML)[</]] の直後に[[名前開始文字]]が続く必要があります。
仕様書の記述は要約に過ぎないと明記されていますから、
SGML の規定を上書きするものではもちろんないのでしょうが、
どんな文字が続いても [CODE(SGML)[</]] は書けないと思っていた方が安全です。

[11] [CODE(HTMLe)[script]] や
[CODE(HTMLe)[style]] は [CODE(SGML)[CDATA]]
なので、中身に [CODE(HTML)[<!--]] とか [CODE(HTML)[-->]]
を書いてもそれは[[注釈宣言]]とは見なされず、[[文字データ]]とみなされます。
そういうのを書いても適宜無視してくれるのは実は HTML
の規定ではなく、[[スタイル言語]]や[[スクリプト言語]]の側の規定に由来します。
[WEAK[そのような規定がない言語では SGML 注釈宣言もどきを書いてはいけないのです。]]

- [12] ''javascipt と CSS と HTML のコメント'' <http://www.parkcity.ne.jp/~chaichan/qanda/qa4530.htm> : [CODE(SGML)[CDATA]] 要素型と注釈宣言もどきについて。 [WEAK[[[WEB相談室]]にしてはまともなやり取りですね:)]]

[43]
[CITE@ja[「CDATA 中の ETAGO」@水無月ばけらのえび日記]] ([CODE[2007-05-24 22:22:13 +09:00]] 版) <http://bakera.jp/ebi/topic/2893>
([[名無しさん]] [WEAK[2007-05-25 01:00:38 +00:00]])

[44]
[CITE[d:id:quaa - 2007-09-02]] ([CODE[2007-09-06 00:14:57 +09:00]] 版) <http://d.hatena.ne.jp/quaa/20070902#p1>
([[名無しさん]])

[45]
[CITE[d:id:quaa - 2007-09-02]] ([CODE[2007-09-06 00:14:57 +09:00]] 版) <http://d.hatena.ne.jp/quaa/20070902#p1>
([[名無しさん]])

[46]
[CITE[d:id:quaa - 2007-09-02]] ([CODE[2007-09-06 00:14:57 +09:00]] 版) <http://d.hatena.ne.jp/quaa/20070902#p1>
([[名無しさん]])


[47]
>>10-

[CODE(SGML)@en[[[CDATA]]]] [[宣言内容]]や
[CODE(SGML)@en[[[CDATA]]]] [[宣言内容]]は、
[CODE(SGML)@en[[[etago]]]] [[文脈依存区切子]]または
([[開始タグ]]が [CODE(SGML)@en[[[nestc]]]]
で終われば) [CODE(SGML)@en[[[net]]]]
をもって終わります [SRC[[[JIS X 4151]]‐1992 6.6]]。

[CODE(SGML)@en[[[etago]]]] は[[文脈的制約]] [CODE(SGML)@en[[[GI]]]]
が満たされれば[[認知]]されます。具体的には、
[CODE(SGML)@en[[[etago]]]] に割当てられた[[文字列]]の後に、
[[名前開始文字]] ([[要素型名]])、
([CODE(SGML)@en[[[SHORTTAG]] [[YES]]]] の場合)
[CODE(SGML)@en[[[tagc]]]] ([[空終了タグ]])、
([CODE(SGML)@en[[[CONCUR]] [[YES]]]] の場合)
[CODE(SGML)@en[[[grpo]]]] ([[文書型指定]])
のいずれかが続けば認知されます [SRC@en[[[JIS X 4151]]‐1992 8.6.2]]。

[[HTML 4]] の場合、
- [CODE(HTML)[[[</]]]] の直後に [CODE(HTML)[[[A]]]]〜[CODE(HTML)[[[Z]]]] または [CODE(HTML)[[[a]]]]〜[CODE(HTML)[[[z]]]]
- [CODE(HTML)[[[</>]]]]
- [[開始タグ]]が [CODE(HTML)@en[[[/]]]] で終わった場合、
[CODE(HTML)@en[[[/]]]]

の一番初めに現れたもので[[内容]]が終了します。
([[名無しさん]])


[[#comment]]


* メモ

- [1] ''マーク付けノート 2001年12月 - マークの付けかた。'' <http://math.oheya.to/markup/notes/n0112c#day26-3>: [CODE(SGML)[CDATA]] と[[属性値]]と[[属性値リテラル]]について。
- [2] [CODE(SGML)[CDATA]] == Character Data == [[文字データ]]。
- [3] [[SGML]] では一般に、[[マーク]]を認知しない[[文字]]の[[並び]]のこと。
- [4] 類似品として [CODE(SGML)[[[PCDATA]]]] (解析文字データ == マークを認知する文字データ) や [CODE(SGML)[[[RCDATA]]]] ([[参照]]を認知する文字データ) がある。

[38] [[XHTML m12n]] の[[抽象モジュール]]定義における[[属性型]]
[CODE(XML)[CDATA]] は、 [[XML 1.0]] の定義によっています。

仕様書:
- [[XHTML m12n]]
-- [CSECTION[4.3. Attribute Types]]
<IW:XHTML1m12n:"abstraction.html#dt_CDATA">