GroovyでHTMLを整形する・その2

2019-02-13Groovy

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).+)(?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とします。

2019-02-13Groovy