#?SuikaWiki/0.9
[1] [[SGML]] における[[空白]]の取扱いや[[正規化]],
周辺事項について。
[[XML//空白]]もあわせて参照されたい。
また、例示は[[規格参照具象構文]]又は [[XML]]
と同じ[[具象構文]]を想定する。
また、ここで「空白」はなんとなくそれっぽい意味(謎)で曖昧に使います。
(詳しい意味は抽象構文・具象構文によりますが、
大体の場合は [CODE(ABNF)[[[SPACE]] / [[RS]] / [[RE]] / [[SEPCHAR]]]] ≒ [CODE(ABNF)[[[SP]] / [[TAB]] / [[CR]] / [[LF]]]] と考えて良いでしょう。)
「[[間隔]]」は、[[文字]] [CODE(char)[SPACE]] を指します。
[WEAK[[[WebSGML]] では、まさに [CODE(ABNF)[[DFN[空白]] = [[SPACE]] / [[RS]] / [[RE]] / [[SEPCHAR]]]] です。 (K.2.4.2)]]
括弧内の番号などは、 [[JISX4151]] の該当部分です。
[[#comment]]
*無視される空白
[2] [[分離子]] [CODE(SGML)[[[s]]]]
([CODE(ABNF)[= SPACE / RE / RS / SEPCHAR ;; (5) ]]) は無視されます。 (5.2.1)
つまり、
- [[文書要素]]の外で、他の[[マーク]]の一部ではない空白
- [[タグ]]の中で、[[属性値表記]]の一部ではない空白
- [[内容モデル]]が[[要素内容]]である要素内の空白
-- [WEAK[例えば、 [[HTML]] の [CODE(HTML)[[[head]]]] 要素の内容であって、子要素・子マークの一部ではない空白。]]
-- ?? マークの最小化の影響で一見これに該当しても無視されない (データタグとかになる) 空白はあり得るか否か?
- [[現対応表]]によって対応付けされておらず、
区切子として認知できるもの (8.4.6)
は無視されます。
[3] [[内容]]の中で、 ([[ISO8879]] 7.6.1, JIS 6.6.1, 参考 3 3.3.3 も参照。)
- [CODE(SGML)[RS]] はマークとして解釈できなければ無視する。
- すべての参照の置換・マークの認知の後に残る [CODE(SGML)[RE]] は、
-= 要素の最初の [CODE(SGML)[RE]] は、その直前に [CODE(SGML)[RS]], [[データ]]又は[[真の部分要素]]がなければ、無視する。
-=- [SAMP(SGML)[[CODE(SGML)[RE]]foo]] -> [SAMP[foo]]
-=- [SAMP(SGML)[[CODE(SGML)[RS]][CODE(SGML)[RE]]foo]] -> [SAMP[[CODE(SGML)[RS]][CODE(SGML)[RE]]foo]] -> [SAMP[[CODE(SGML)[RE]]foo]]
-=- [SAMP(SGML)[data[CODE(SGML)[RE]]foo]] -> [SAMP[data[CODE(SGML)[RE]]foo]]
-=- [SAMP(SGML)[[CODE(SGML)[RE]]foo]] -> [SAMP[[CODE(SGML)[RE]]foo]]
-=- [SAMP(SGML)[[CODE(SGML)[RE]]foo]] -> [SAMP[foo]]
-=- [SAMP(SGML)[[CODE(SGML)[RE]]foo]] -> [SAMP[foo]]
-= 要素の最後の [CODE(SGML)[RE]] は、その直後にデータ又は真の部分要素がなければ、無視する。
-= [CODE(SGML)[RS]] 又は [CODE(SGML)[RE]] の直後に位置しない [CODE(SGML)[RE]] は、その前にデータ又は真の部分要素がなければ、無視する。
-=- [SAMP(SGML)[foo[CODE(SGML)[RE]]bar]] -> [SAMP[foo[CODE(SGML)[RE]]bar]]
-=- [SAMP(SGML)[[CODE(SGML)[RE]][CODE(SGML)[RE]]bar]] -> [SAMP[bar]]
-=- [SAMP(SGML)[[CODE(SGML)[RE]][CODE(SGML)[RE]]foo]] -> [SAMP[[CODE(SGML)[RE]][CODE(SGML)[RE]]foo]]
-=- [SAMP(SGML)[[CODE(SGML)[RE]][CODE(SGML)[RE]]foo]] -> [SAMP[foo]]
-= 以上に該当しない場合は、データとする。
--[4]
> [CODE(SGML)[RE]] をデータとするかどうかの判定は、
マークの認知の過程で行う。マークの認知に、
タグの省略の認知を含めて、 (1)〜(3)に従って
[CODE(SGML)[RE]] か無視できるかどうかの判定に先立って行う。
この手順では、
[PRE[
(quote | #PCDATA)*
]PRE]
のように、要素の内容のどこにでもデータが現れ得る通常の場合、
直感に合った結果が得られる。しかしながら、
[PRE[
(x, #PCDATA)
]PRE]
のように、内容モデルがデータの現れ得る位置に制限を課す場合には、
(1)又は(2)の状況がマークの認知の最中に誤りとなることがある。
このような内容モデルは、通常必要としないので、推奨しない
(10.2.4 参照)。
[5] >>3 の例 (JIS X 4151 より):
[PRE[
[CODE(SGML)[RS[INS[[SUB[1]]]]]] record 1 [CODE(SGML)[RE[INS[[SUB[1]]]]]]
[CODE(SGML)[RS[INS[[SUB[2]]]]]] record 2 [CODE(SGML)[RE[INS[[SUB[2]]]]]]
[CODE(SGML)[RS[INS[[SUB[3]]]]]] record 3 [CODE(SGML)[RE[INS[[SUB[3]]]]]]
]PRE]
で、要素 [SAMP(SGML)[outer]] について考える。
[CODE(SGML)[RE[INS[[SUB[1]]]]]] 及び
[CODE(SGML)[RS[INS[[SUB[2]]]]]] は子要素内にあるので、
ここでは考えないことになる。従って、
[CODE(SGML)[RE[INS[[SUB[2]]]]]] が内容の最初の
[CODE(SGML)[RE]] である。
さて、 [SAMP(SGML)[sub]] が真の部分要素であるなら、
この [CODE(SGML)[RE[INS[[SUB[2]]]]]] はデータとなるが、
[[添加要素]]であれば、前にデータも真の部分要素も無いので、
無視される。
要素 [SAMP(SGML)[sub]] について、最初の [CODE(SGML)[RE]]
は [CODE(SGML)[RE[INS[[SUB[1]]]]]] である。
その前にはデータも真の部分要素も無いので、無視する。
[6] 添加要素とか真の部分要素とか、なんでこんなややこしい規則があるんだろう?
[21] >>6 参考3 3.3.1 参照。それっぽいことが書いてある。
(処理指令だけの[[記録]]を無視するとか。)
[7] >>3 の続き。 [CODE(SGML)[RE]] は、それに続く最初のデータ又は真の部分要素の直前に位置するものとして扱います。
つまり、その間に他のマークがある場合、その後に位置するものとします。
ずなわち、 [SAMP(SGML)[foo[CODE(SGML)[RE]]bar]] -> [SAMP[foo[CODE(SGML)[RE]]bar]],
[SAMP(SGML)[foo[CODE(SGML)[RE]]bar]] -> [SAMP[foo[CODE(SGML)[RE]]bar]]。
[WEAK[(なんでこんな面倒な規則があるんだろう?)]]
[22] 参考3 3.3.1 の例で、
[PRE[
最初のデータ
最後のデータ
]PRE]
と
[PRE[
最初のデータ
最後のデータ
]PRE]
は同値って書いてある。で、 >>7 によれば更に
[PRE[
最初のデータ
最後のデータ
]PRE]
と同値と解釈されるのか?
[8] なお、 >>3-8 で、「データ」として扱うのは通常の意味のデータのほかに、
[[特定文字データ実体]], [[非SGML実体]], [[SGML部分文書実体]]も含んでいます。[WEAK[[[処理指令実体]]は含みません。]]
[WEAK[これについては直感とおおむね一致する動作でしょう。]]
[9] [CODE(SGML)[[[参照終了]]]]である [CODE(SGML)[RE]]
は無視されます (8.4.5)。例えば、
[PRE[
&ref[CODE(SGML)[RE]]
[CODE(SGML)[RS]]non-ref
]PRE]
→ [SAMP[[VAR[ref]]non-ref]]
[26] このわけのわかんない複雑な規則は、
[[WebSGML]] で [CODE(SGML)[[[KEEPRSRE]] YES]]
にしている場合には適用されません。
[[混合内容]]中の全ての[[空白]]は、
[[データ文字節]]として[[グローブ]]中に含まれ、
[[要素内容]]中の全ての空白は、
[[s分離子節]]としてグローブ中に含まれます。
(K.3.8.2 参照。)
[[#comment]]
*マーク最小化と空白
[3] [[データタグ雛形]]と[[内容]]との照合は、その内容の
[[マーク]]の[[認知]]及び[[参照]]の[[解決]]を行った後で、
[CODE(SGML)[RS]] および [CODE(SGML)[RE]]
を無視する前に行います。
(6.3.2)
[[#comment]]
*表記の中の空白と正規化
-[[属性値//正規化]]
-[[最小表記]]
[18] [[引数表記]]には、それ自体には空白と正規化についての規定はありません。
[[#comment]]
*実体参照・文字参照
[15] [[文字参照]]には[[数値文字参照]]と[[名前文字参照]]があります。
前者は常に[[データ]]として、後者は生の文字と同等として扱われます。 (8.5)
例えば、 [SAMP(SGML)[&refRE;]] と
[SAMP(SGML)[&ref[CODE(SGML)[RE]]]]
は同値で、 [SAMP(SGML)[&ref;]] とほぼ同じ意味です。
一方、 [SAMP(SGML)[&ref
]] は
[SAMP(SGML)[&ref;
]] と同値で、後半は SGML
的な意味を持たない単なる文字 [CODE[0x0D]] です。
[[#comment]]
** 短縮参照と空白
[12] [[短縮参照]]について (8.4.6)。
- 短縮参照が[[現対応表]]により[[一般実体]]に対応付けてある場合には一般実体に置換しますが、そうでない場合には、
-- 区切子として認知できるなら、分離子 [CODE(SGML)[s]] とみなし、結果無視します (>>2)。
-- できないなら、データとして扱います。
[13] 8.4.6.1 では、[DFN[同値な参照列]]が規定されています。
短縮参照を[[名前実体参照]]に置換する必要がある時に、
[[記録]]が長くなり過ぎないようにするための措置らしいです。
,短縮参照に含まれるか否か,==,同値な参照列
,[CODE(SGML)[RS]],[CODE(SGML)[RE]],
,×,×,[CODE(ABNF)[[[ero]] [[名前]] [[refc]]]]
,○,×,[CODE(ABNF)[RS ero [[名前]] refc]]
,×,○,[CODE(ABNF)[ero [[名前]] RE]]
,○,○,[CODE(ABNF)[RS ero [[名前]] RE]]
内容の [CODE(SGML)[RS]] は無視されるし参照終了の
[CODE(SGML)[RE]] もデータにならないので本当に同値で、
この変換は影響が無いそうです。
[14] で、次の例でも影響が無いんでしょうか?
[PRE[
[INS[...]]
[VAR[RS;&ref;]]foo
]PRE]
う〜ん。。。
[16] 短縮参照の定義では特殊な文字列として[[B列]]があります。
その中では文字 [CODE(SGML)[B]] が1つの空白に対応します。
詳しくは[[短縮参照]]を参照。 (8.6.5)
[[#comment]]
* 内容中の空白の保持 ― Web SGML
[24] [[WebSGML]] K.3.8.2 では、新しい[[他機能]]
[CODE(SGML)[[[KEEPRSRE]]]] を定義しています。
[[SGML宣言]]でこの機能を [CODE(SGML)[YES]]
にすると、 [[ISO8879]]:1986 7.6.1 == JIS X 4151‐1992
6.6.1 == >>3,>>7 は無視されます。
つまり、[[混合内容]]中の全ての空白は、[[データ文字節]]として[[グローブ]]に含まれ、
[[要素内容]]中の全ての空白は、 [[s分離子節]]としてグローブに含まれます。
なお、この機能が影響するのは要素内容の空白だけです。
属性値表記などでの規則は変化しません。
[25] [[XML]] の [CODE(XML)[[[xml]]:[[space]]]]
辺りとこの機能が関連しているといえます。
[[#comment]]
*メモ