Today's the day

在那毁灭之路,逆流而上


原来有个 reset_session

自动闭合 html 标签简化版

galeki posted @ 2008-04-29 04:12PM in Ruby&Rails进修 with tags html 闭合
return false 在 IE 下失效了?

Chito 现在用 Rubyful Soup 来解决 html 没有正确闭合的问题,其中的 BeautifulSoup 类的 prettify 方法非常强大,几乎可以修正 html 中的所有错误。

不过 Chito 只是拿来闭合标签,其他的功能完全用不到,Rubyful Soup 还要依赖 htmltools 这个库,为了个闭合标签就要多附带这么多库太不爽了,而且还有个 %nbsp 的 bug。

自己尝试写了个,close_html:

  1. def close_html(html)
  2.     stream = html.scan( /<\s*[^>]+>/ ).map {|x| x[ /<\s*([^>^\s]*)[^>]*>/ , 1]}
  3.     stack = []
  4.     stream.each do |x|
  5.         if x =~ /^\//
  6.             stack.pop if x[1..-1] == stack.last
  7.         else
  8.             stack.push x
  9.         end
  10.     end
  11.     stack.reverse.each {|x| html << "</#{x}>\n"}
  12.     html
  13. end

处理的方式罗嗦了一些,先把 html 文本中的标签提取出来,然后再去掉属性之类的,转换成一个 “标签流”,比如:

<div class="main><ul><li>test</li>

就转换成了:

["div","ul","li""/li"]

接着读取上面这个流,把开始标签压栈,遇到以 / 开头的结束标签,检查是否和栈顶的标签相匹配,匹配就弹出,走完标签流后,还留在栈里的标签就是需要闭合的标签了。

测试一下:

  1. test_html = <<END
  2. <div>
  3.     <ul>
  4.         <li> lalalalala </li>
  5.         <li><strong><a href="http://www.google.com"> Google
  6. END
  7.  
  8. puts close_html(test_html)

输出:

  1. <div>
  2.     <ul>
  3.         <li> lalalalala </li>
  4.         <li><strong><a href="http://www.google.com"> Google
  5. </a>
  6. </strong>
  7. </li>
  8. </ul>
  9. </div> 

效果不错,标签都正确闭合了~

这种方法还是有局限性的,因为只是个简单的栈操作,所以只适合修正那些正确的 html 被拦腰截断的情况,而不能修正类似 <h1></h2> 这样匹配错误的情况,<div><a></div> 这样中间格式错误的情况也不行,不过 Chito 的编辑器和 textile 都不会生成这些样子的 html,所以完全可以用这个小函数替代那个庞大的 Rubyful Soup 了~

全局相关文章
相关文章

Comments Feed

1
Cite weskycn [Guest] posted @ 2008-04-30 08:55AM
楼主说得好阿。我顶, 拿回来用一下,呵呵。 不过我的项目是这样设计的,Episode 里有两个字段:brief和body,发布episode的时候程序自动把body字段截取500个字符赋予brief字段,也就是说brief字段不会让用户自己填写,这就有可能出现 中间格式错误的情况 了。 我这样做合理么?

Head_small
galeki

如果你可以保证 body 字段的 html 没错误的话,用这个方法就可以。

不过如果只是截取固定的 500 个字符,那么假如有一篇文章,一开始就是大量的 html 样式,岂不会什么内容也截取不到?

如果设计允许的话,应该把 html 标签去掉再截取,这样最保险,虽然就没了样式。


3
Cite weskycn [Guest] posted @ 2008-05-04 10:53AM
把 html 标签去掉再截取.这个方法好,呵呵,本来就是简介嘛,没有必要加入样式,多谢了。。

Head_small
galeki

而且也比较安全



* Login
*