見出し画像

HTMLタグ名の仕様はパーサーの仕様にあり

決着した。前回のHTMLタグ名の仕様が謎だったのが解決したのでまとめておく。

というのも前回の記事を読んでいただ方にご助言いただき、あっさりと謎は解けた。そめ(@_tsmd)さんありがとうございます。

パーサーの仕様

タグ名の仕様は少なくとも3箇所あった。①HTMLの仕様 ②DOMの仕様 ③HTMLパーサーの仕様。ご指摘どおりで恥ずかしいばかりなんだけど、いったいなんでパーサーの話をしているのにパーサーの仕様を読まねぇんだっつう話。言い訳としてはパーサーの仕様が書かれていることをすっかり忘れていたのと、①のHTMLの仕様に絶対書かれていると思って疑わなかったからだ(最初は)。

で、肝心のパーサーの仕様書なんだけど、これがまあ最初は意味がわからない。ここはまだ翻訳されていない部分でもあるので英語で読む必要がある(翻訳機も使ったけど)。アドバイスをもらった項目は 12.2.5.8 Tag name state で、「タグの状態」とある。状態ってなんぞ??といろいろ全体的に見ていったところ、これはパーサーの処理の中でもTokenization(字句解析)にあたる処理の一部で、この説明そのものがプログラムになっている。つまり、通常プログラミング言語で書くはずのコードをそのまま文章にして順を追って説明しているのだ。このような仕様書を読んでなかったこともあって、ものすごく新鮮で読むのが楽しかった。プログラミングをしたことがある人は一度読んでみてほしい。英語だけど、翻訳機を通したものと交互に読むとだいたい把握できる。

タグ名の正規表現

仕様を掻い摘んで要約すると、①1文字目はアルファベット②2文字目移行はタブ、ラインフィード、書式フィーダ、半角スペース、スラッシュもしくはヌル文字以外の任意の文字、となる。ゆるい!思ったより全然ゆるい!全角スペースすら許容するとは!!カスタム要素よりもゆるい(前記事参照)。

正規表現で表すとこうだ。

/^(?:[a-z][^\u0000\u0009\u000A\u000C\u0020\/>]*)/i

なぜパーサーを書いたのか

そもそも論として、markuplintは内部的にparse5というOSSのHTMLパーサーを利用している。ならなんで仕様を調べてまでパーサー書かないといけないのかというと、parse5は本当に仕様書通りにパース処理を行っているので結果的に大文字小文字の区別がつかない状態でASTが返ってくる。正確にはASTではなくASTっぽいキャラクタ位置情報をもったDOMオブジェクトだ。そうなると、markuplintで実現したかった大文字で書かれていたら警告を出すが実現できなかった。なので全体はやらないけどタグ名や属性名の部分だけでも独自に実装する必要があった。

当初なんで大文字小文字の区別がつかない情報しか受け取れないのかさっぱりわからなかったんだけど、仕様書の説明内の手続きにちゃんとアルファベットは小文字に変換してからタグ名に追加すると書いてあった。そしてparse5のソースコードを読むと、それは丁寧に仕様どおりの手続きでプログラムが組まれていた。なぜ最初からこれを確認したかったたんだ俺は。

ということで、とてもとてもスッキリしたところでmarkuplintの開発を続けたいと思います。引き続き応援よろしくお願いします。

この記事が気に入ったらサポートをしてみませんか?