02月26, 2012

Fl:支持模板语法的HTML词法解析

从这篇文章开始陆续介绍Fl里功能的实现方式,但更多的是开发这些功能需要注意的点。下面从支持模板语法的HTML词法解析开始。

HTML语法

我们先来看下w3c对于HTML语法的说明, 可以从http://www.w3.org/TR/html5/syntax.html了解,主要包含下面几个方面。

1、The DOCTYPE

2、Elements

3、Text

4、CDATA

5、Comments

虽然w3c对于HTML语法就几个分类,对真正处理的时候需要注意非常多的事情。

HTML词法分析需要注意的地方

1、需要处理模板语法(如: <&if $name&><div><&$name&></div><&/if&>等模板语法)

2、<!--[if, ]>, ]>-->, <![endif, ]-->, <!--<![endif, ]-->等组合在一起的IE条件注释,不能当作注释处理了

3、<script>和<style>标签内的处理

4、<textarea>和<pre>标签内容的特殊处理

5、<!--status ok-->这种注释的特殊处理(一般网站会通过这种方式检测当前服务是否正常,所以页面内要加上这个特殊的注释)

6、<?xml >可能是个XML

7、<![CDATA[, ]]>内容的特殊处理

8、对于模板语法左右定界符可能出现<和>的处理

9、属性值两边的引号与模板语法里的引号的优先级处理。(如:<div name="<&if $name="welefen"&>suredy<&/if&>">welefen</div>)

10、对于tag的正确解析,如果当前token结果是<>,它并不是tag,而是text。

11、对于text内容出现<和>的处理,如:<div>welefen<<<</div>,这里获取到的text是welefen<<<。

介于这些要注意的地方,分析的token结果有下面这些类型。

Token类型

//模版
 define ( 'FL_TOKEN_TPL', 'tpl' );
 //pre标签
 define ( 'FL_TOKEN_HTML_PRE_TAG', 'pre' );
 //textarea标签
 define ( 'FL_TOKEN_HTML_TEXTAREA_TAG', 'textarea' );
 //html的开始标签
 define ( 'FL_TOKEN_HTML_TAG_START', 'tag_start' );
 //html的结束标签
 define ( 'FL_TOKEN_HTML_TAG_END', 'tag_end' );
 //script标签
 define ( 'FL_TOKEN_HTML_SCRIPT_TAG', 'script' );
 //style标签
 define ( 'FL_TOKEN_HTML_STYLE_TAG', 'style' );
 //IE hack
 define ( 'FL_TOKEN_HTML_IE_HACK', 'ie hack' );
 //static ok,用于服务器监控
 define ( 'FL_TOKEN_HTML_STATUS', 'status' );
 //text node
 define ( 'FL_TOKEN_HTML_TEXT', 'text' );
 //doc type
 define ( 'FL_TOKEN_HTML_DOCTYPE', 'doc type' );
 //xml head <?xml
 define ( 'FL_TOKEN_XML_HEAD', 'xml head' );
 //xml cdata
 define ( 'FL_TOKEN_XML_CDATA', 'xml cdata' );
对于注释,为了后续处理的方面,不作为一个单独的token,而是作为附近一个token的属性处理。 对于具体实现,可以从这里查看: [https://github.com/welefen/Fl_new/blob/master/src/Lang/Html/Token.class.php](https://github.com/welefen/Fl_new/blob/master/src/Lang/Html/Token.class.php) ## token分析结果示例 如:
{=if $name==11=}
 <div></div>
 {=else=}
 <div class="
 {=if $name=="welefen"=}welefen
{=else=}suredy{=/if=}"
 style="color:red;boder:{=$border=}"
 >welefen
{=value=}
 </div>
分析结果如下:
Array
(
 [0] => Array
 (
 [type] => tpl
 [value] => {=if $name==11=}
 [line] => 0
 [col] => 0
 [pos] => 0
 [newlineBefore] => 0
 [commentBefore] => Array
 (
 )
)
[1] => Array
 (
 [type] => tag_start
 [value] => <div>
 [line] => 1
 [col] => 1
 [pos] => 18
 [newlineBefore] => 1
 [commentBefore] => Array
 (
 )
)
[2] => Array
 (
 [type] => tag_end
 [value] => </div>
 [line] => 1
 [col] => 6
 [pos] => 23
 [newlineBefore] => 0
 [commentBefore] => Array
 (
 )
)
[3] => Array
 (
 [type] => tpl
 [value] => {=else=}
 [line] => 2
 [col] => 0
 [pos] => 30
 [newlineBefore] => 1
 [commentBefore] => Array
 (
 )
)
[4] => Array
 (
 [type] => tag_start
 [value] => <div class="
 {=if $name=="welefen"=}welefen

 {=else=}suredy{=/if=}"
 style="color:red;boder:{=$border=}"
 >
 [line] => 3
 [col] => 1
 [pos] => 40
 [newlineBefore] => 6
 [commentBefore] => Array
 (
 )
)
[5] => Array
 (
 [type] => text
 [value] => welefen

 [line] => 8
 [col] => 2
 [pos] => 152
 [newlineBefore] => 0
 [commentBefore] => Array
 (
 )
)
[6] => Array
 (
 [type] => tpl
 [value] => {=value=}
 [line] => 10
 [col] => 1
 [pos] => 163
 [newlineBefore] => 0
 [commentBefore] => Array
 (
 )
)
[7] => Array
 (
 [type] => tag_end
 [value] => </div>
 [line] => 11
 [col] => 0
 [pos] => 173
 [newlineBefore] => 1
 [commentBefore] => Array
 (
 )
)
)

本文链接:http://welefen.com/post/html-tokenize-support-tpl.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。