鳩丸よもやま話

bakera.jp > 鳩丸よもやま話 > マーク区間とは

マーク区間とは

マーク区間とは

SGML には、マーク区間 ("marked section"、マーク指定区域とも言います)という便利な仕組みがあります。まず、ルールをざっと説明しましょう。

マーク区間は、"<![" で始まり、キーワード(状態見出し語)、"[" 、内容、"]]>" という形で構成されます。そこで指定されるキーワードによって内容の扱いが変わります。

キーワード "INCLUDE" は、その部分が「含まれる」、すなわち普通に表示されたり解釈されたりすることを意味します。

<![INCLUDE[
<P>この部分は INCLUDE ……表示/解釈されます。</P>
]]>

キーワード "IGNORE" では、区間内は無視されます。

<![IGNORE[
<P>この部分は IGNORE ……無視されます。</P>
]]>

キーワード "CDATA" では、区間内は CDATA として扱われます。マーク区間終了区切り子 "]]" を除く全ての文字はデータとして扱われます。

<![CDATA[
この部分は CDATA として扱われ、
< や > はタグの区切り子としては解釈されません。
&amp; なんて書くとそのまま &amp; と表示されますし、
<!--コメントも無効ですからこの部分もしっかり表示されます。-->
]]>

同様に、キーワード "RCDATA" を用いると、区域内を RCDATA として扱います。

キーワード "TEMP" は、その区間を一時的なものとします。扱いは INCLUDE と同じです。

よく使われるのは、INCLUDE と IGNORE です。XML では CDATA型の内容をもつ要素が使えないことになっているので、CDATA も割と良く使われるようです。

マーク区間の使い方

マーク区間は、うまく使うと非常に便利なものです。たとえばこのように……。

<!ENTITY % test.section "INCLUDE">

……

<![%test.section;[
<H1>テスト区間</H1>
<P>テスト区間です。とりあえず表示はされる予定です。</P>
<P>INCLUDE を IGNORE に変えれば無視されます。</P>
]]>

……

<![%test.section;[
<H1>テスト区間再び</H1>
<P>またテスト区間です。とりあえず表示はされる予定です。</P>
]]>

パラメータ実体を使っておくと、先頭行の "INCLUDE" を "IGNORE" に書き換えるだけで、複数の箇所を一度に無効にできます。有効/無効の切り替えが簡単にできるわけです。もう少し複雑な例だと、こんなものがあります。

<!ENTITY % foo.deprecated "IGNORE">
<![%foo.deprecated;[
<!ENTITY % foo.recommended "IGNORE">
]]>

<!ENTITY % foo.recommended "INCLUDE">

……共通部分……

<![%foo.recommended;[
この部分は厳格な推奨仕様
]]>

<![%foo.deprecated;[
この部分は非推奨仕様
]]>

……共通部分……

最初の行で foo.deprecated が IGNORE とされているため、次のマーク区間は無視され、その次の宣言で foo.recommended が INCLUDE とされます。よって、以下 foo.recommended の部分は含まれ、foo.deprecated の部分は無視されます。

最初の行の IGNORE を INCLUDE とすると、次のマーク区間が有効となり、foo.recommended は IGNORE とされます。次の宣言は無視されませんが、先の宣言と重なるため無効です。よって、最初の場合と比べて、ちょうど INCLUDE と IGNORE が正反対になります。

このような手法は文書型定義の中でよく見かけるものですが、文書インスタンス(本文)の中でも使うことが出来ます。いや、これは面白そうです……。

マーク区間は使うべきか

しかし、残念なことに、現実にはマーク区間を理解してくれるブラウザは皆無です。悲しいことに、ブラウザはマーク区間を単なるタグとみなして、訳の分からない表示をしたります。多くのブラウザでは、一番最初の INCLUDE の例文で "]]>" が表示されてしまいます。ですから、HTML 文書にはこんな小細工をしないようにした方が賢明です。

XML / XHTML のマーク区間

XML の場合は、CDATA 区間だけが使えることになっています。他のマーク区間は使用することができませんが、CDATA 区間はどのパーサもちゃんとサポートしているので、使っても問題ありません。よって CDATA 区間を有効活用したいところですが、CDATA 区間内では "]]>" という文字列が書けませんし、文字参照も使えないので注意が必要です。

XHTML の場合でも CDATA 区間は使えます。特に XHTML では script要素style要素の中身が #PCDATA になっているため、HTML と違って & や < などをそのまま書くことができません。従って、CDATA区間を使って書くことになります。

……が、CDATA 区間をうまく解釈しないブラウザも多いので難しいところです。特に、「script要素を解釈しないブラウザからスクリプトの内容をコメントアウトする」処理は、CDATA 区間の中に書けば CDATA 区間開始・終了の区切り子がコメントアウトできませんし、外に書けば CDATA 区間そのものがコメントアウトされてしまいます。二進も三進も行きません。

※このことを踏まえて、Another HTML-lint では「スクリプトやスタイルは外部ファイルにするべし」という主旨の警告が出るようになっています。外部ファイルになっていれば、コメントアウトの問題も、CDATA / #PCDATA の問題も発生しません。

最近の日記

関わった本など