2008/10/23

groovyでhtmlを整形する・その2

HTML整形スクリプトを改修。formatメソッド(クロージャだけど)にFileオブジェクトを渡すと、フォーマットされたHTMLを返します。

ただし、XmlSluperは厳密にXMLをチェックするので、正確にはXHTMLしかチェック出来ません。XML整形スクリプトにすればよかったかな。

それから、$nbspなどの文字が含まれていた場合にも正常に動作しないようです・・・。

final NO_INNER_TAG_LIST = ["input", "br", "link", "meta", "hr"]
final SPACES = 4
final xmlSlurper = new XmlSlurper()
formatNode = { node, hierarchyNum ->
    
    def result = ""

    def indent = " "*hierarchyNum*SPACES
    def name = node.name()
    
    def startTag = ([name] + node.attributes().collect{ "${it.key}=\"${it.value}\"" }.sort()).join(" ")

    def children = node.children()
    if( !children.isEmpty() ){
        def parts = []
        parts << indent + "<" + startTag + ">"
        parts << children.collect{ formatNode(it, hierarchyNum + 1) }.join("\n")
        parts << indent + ""
        result = parts.join("\n")
    } else {
        if( NO_INNER_TAG_LIST.contains(name) ){
            result = indent + "<" + startTag + " />"
        } else {
             result = indent + "<" + startTag + ">" + node.text().trim() + ""
        }
    }

    result
}

def format = { file ->
    def htmlText = ""
    def xmldefText = ""
    def htmlStartText = ""
    // xml定義やdoctypeを抜いておかないとエラーになるので
    // また、html内部のxmlns設定が消えてしまうので、保存
    (file.getText("UTF8") =~ /((?ms).*)((]*>)(?ms).+<\/html>)(?ms).*/).each{ all, xmldef, htmldef, htmlstart ->
        xmldefText = xmldef
        htmlText = htmldef.replace("\t","    ")
        htmlStartText = htmlstart
    }

    def html = xmlSlurper.parseText(htmlText)


    def result = xmldefText + formatNode(html, 0)
    result.replaceAll(/]*>/, htmlStartText)
}
println format(new File("/home/genzou/test.html"))

今のプロジェクトのHTMLは整形できたので、自分の中でOKとします。

0 件のコメント:

コメントを投稿