Cocurrent Clean: Wiki記法

Wiki記法の実装中。使い慣れているhatena風で。
このへんはCleanの書きやすさが生きてくる。とりあえず、書きかけのコード。

implementation module Wiki

import OptHtml, ViewBase, StdBase, OptEnv

conv :: !String -> HtmlData
conv data
    # (_,data) = foldl convert ([NORMAL],[]) (map rtrim $ data splitOn '\n')
    = HtmlData $ reverse data

::WikiState = NORMAL | PRE | UL | OL

substring data i = data % (i, size data - 1)
enclose state res stag etag data
    = (state, [HtmlRaw etag, HtmlText data, HtmlRaw stag:res])

convert :: ([WikiState],[HtmlData]) String -> ([WikiState],[HtmlData])
convert (ws=:[NORMAL:_], res) ">|" = ([PRE:ws], [HtmlRaw "<pre>":res])
convert (ws=:[NORMAL:_], res) ">>" = (ws, [HtmlRaw "<blockquote>\r\n":res])
convert (ws=:[NORMAL:_], res) "<<" = (ws, [HtmlRaw "</blockquote>\r\n":res])
convert (ws=:[NORMAL:_], res) data
    = case [c \\ c <-: data] of
        []        = (ws, [HtmlRaw "<br />\r\n":res])
        ['***':_] = enclose ws res "<h3>" "</h3>\r\n" (substring data 3)
        ['**':_]  = enclose ws res "<h2>" "</h2>\r\n" (substring data 2)
        ['*':_]   = enclose ws res "<h1>" "</h1>\r\n" (substring data 1)
        ['-':_]   = convert ([UL:ws], [HtmlRaw "<ul>\r\n":res]) data
        ['+':_]   = convert ([OL:ws], [HtmlRaw "<ol>\r\n":res]) data
        _         = enclose ws res "<p>" "</p>\r\n" data

convert ([PRE:ws], res) "|<" = (ws, [HtmlRaw "</pre>\r\n":res])
convert (ws=:[PRE:_], res) data = (ws, [HtmlRaw "\r\n", HtmlText data:res])

convert ([UL:ws], res) data
    = case [c \\ c <-: data] of
        ['-':_] = enclose [UL:ws] res "<li>" "</li>\r\n" (substring data 1)
        _       = convert (ws, [HtmlRaw "</ul>\r\n":res]) data

convert ([OL:ws], res) data
    = case [c \\ c <-: data] of
        ['+':_] = enclose [OL:ws] res "<li>" "</li>\r\n" (substring data 1)
        _       = convert (ws, [HtmlRaw "</ol>\r\n":res]) data