Dev Study
← 解説「自己終了タグと script の中身 — 「適切な終了タグ」が来るまでは全部文字」に戻る

サンプルコードで身につける: 自己終了タグと script の中身 — 「適切な終了タグ」が来るまでは全部文字

解説で学んだ概念を、3つの具体例で確認します。素朴な例から実務寄りの例へと進みます。

1自己終了タグ: / の次が > のときだけ

SelfClosingStartTag(13.2.5.40)は「/」を読んだ直後ので、次が「>」ならフラグを立ててタグを出し、それ以外なら「/」を無視しての前に戻ります()。はフラグを立てるだけで、それをどう扱うかは木構築側です。実行すると <br/> と <br /> と <input disabled/> と <div/> は =true、<br> は false、そして <br/ > は「/」の次が空白なので false になります。

Rust

2script の中身は文字: 適切な終了タグ・temp・pending

<script> の中では「<」をタグにせず(、13.2.5.4)、「</」の後に読んだ文字を temp に控えながら終了タグ名を組み、最後に出した開始タグと同じ名前(「」)で「>」が来たときだけ EndTag にします。違っていれば「</」+ temp を文字として流し直しますが、1 回の遷移で出せるは 1 つなので、残りは pending()に積んで次の呼び出しで先に出します。実行すると if (a < b) { x = '</div>'; } の中の </div> は文字のまま残って </script> で終わり、s = "</scrip" + "t>"; では </scrip の直後が '"' なので終了タグにならず文字に戻り、大文字の </SCRIPT> が小文字の script として一致して終わります。

Rust

3実務: {{name}} のテンプレートを temp と pending で読む

「{」を 1 つ見ただけでは placeholder か文字か決まらない、という問題は script data の「</」と同じ形です。OpenBrace で次が「{」でなければ「{」と今の文字を pending に積んで文字として流し、Placeholder の中では temp に名前を控え、CloseBrace で「}}」が揃ったときだけ置き換え、入力の終わりに開いたままなら temp を文字として戻します。実行すると {{name}} と {{ count }} が kazu と 3 に置き換わり、JSON の {"a":1} や {そのまま} は手を付けられず、未定義の {{nope}} は <nope が未定義>、閉じていない {{unfinished はそのまま残ります(設定ファイルの変数展開やメールの定型文で同じ考え方が出ます)。

Rust

図やコードに出てくる用語(タップで説明)