»
S
I
D
E
B
A
R
«
Testing BlogLiterally, and HTML DSL changes
Nov 3rd, 2009 by Axman6

Robert Greayer has just released his BlogLiterally program on hackage, so I thought I’d try it out. I’ve made some small changes to the HTML DSL I’ve been working on since i last posted, which I’ll outline here:

The HTML type is now

data HTML a = Doctype String String String (HTML a)
            | Content a
            | Text String
            | Node Tag Attrs [HTML a]
            | NoContent Tag Attrs
            | Comment String
            deriving Show

instead of

data HTML a = Doctype String String String [HTML a]
            | Content a
            | Text String
            | Node Tag Attrs [HTML a]
            | NoContent Tag Attrs
            | Comment String
            deriving Show

I’ve also added some more helper functions:

addAttrs :: Attrs -> HTML a -> HTML a
addAttrs attrs (Node tag attrs' rest) = Node tag (attrs' ++ attrs) rest
addAttrs attrs (NoContent tag attrs') = NoContent tag (attrs'++attrs)
addAttrs _ x = x

toTable :: [[String]] -> HTML a toTable xss = table . map (tr . map (\x -> td [text x])) $ xss

toTable' :: Show a => [[a]] -> HTML b toTable' = toTable . map (map show)

And updated my example:

example :: HTML ()
example =
    doctype "html PUBLIC"
            "-//W3C//DTD XHTML 1.0 Transitional//EN"
            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" $
        xhtml [
            header [
                title "My random page",
                meta "name" "Alex"
            ],
            body [
                comment "This is a comment",
                para [
                    text "The hr tag defines a horizontal rule:"
                ],
                hr,
                para [
                    text "This is a paragraph"
                ],
                hr,
                para [
                    text "This is a paragraph"
                ],
                addAttrs [("border","1px")] . toTable' $ [[0..n] | n <- [0..3]]
            ]
        ]

Which produces this html:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
        <head >
            <title >
                My random page
            </title>
            <meta name="name" content="Alex"/>
        </head>
        <body >
            <!-- This is a comment -->
            <p >
                The hr tag defines a horizontal rule:
            </p>
            <hr />
            <p >
                This is a paragraph
            </p>
            <hr />
            <p >
                This is a paragraph
            </p>
            <table border="1px">
                <tr >
                    <td >
                        0
                    </td>
                </tr>
                <tr >
                    <td >
                        0
                    </td>
                    <td >
                        1
                    </td>
                </tr>
                <tr >
                    <td >
                        0
                    </td>
                    <td >
                        1
                    </td>
                    <td >
                        2
                    </td>
                </tr>
                <tr >
                    <td >
                        0
                    </td>
                    <td >
                        1
                    </td>
                    <td >
                        2
                    </td>
                    <td >
                        3
                    </td>
                </tr>
            </table>
        </body>
    </html>

An HTML DSL in Haskell in one day
Nov 2nd, 2009 by Axman6

So, after a discussion on #haskell, I decided to try writing a simple HTML DSL in Haskell. In about 15 minutes, I had a rather rudimentary implementation, and after a day or so of working, I’ve got a somewhat useful DSL for writing HTML, and pretty printing it.

The main type behind the package is:

data HTML a = Doctype String String String [HTML a]
            | Content a
            | Text String
            | Node Tag Attrs [HTML a]
            | NoContent Tag Attrs
            | Comment String
            deriving Show

where

type Attr = (String, String)
type Attrs = [Attr]
data Tag = Html
         | ARef
         | BlockQuote
         | Body
         ...
         | Title
         | TR
         | UL

I’ve also provided helper functions to make this an actual DSL (I guess?):

example :: HTML ()
example = 
    doctype "html PUBLIC" "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [
        xhtml [
            header [
                title "My random page",
                meta "name" "Alex"
            ],
            body [
                comment "This is a comment",
                para [
                    text "The hr tag defines a horizontal rule:"
                ],
                hr,
                para [
                    text "This is a paragraph"
                ],
                hr,
                para [
                    text "This is a paragraph"
                ],
                table [
                    tr [
                        td [
                            text "data"
                        ],
                        td [
                            text "more data"
                        ]
                    ],
                    tr [
                        td [
                            text "more data"
                        ]
                    ]
                ]
            ]
        ]
    ]

produces:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head >
        <title >
            My random page
        </title>
        <meta name="name" content="Alex"/>
    </head>
    <body >
        <!-- This is a comment -->
        <p >
            The hr tag defines a horizontal rule:
        </p>
        <hr />
        <p >
            This is a paragraph
        </p>
        <hr />
        <p >
            This is a paragraph
        </p>
        <table >
            <tr >
                <td >
                    data
                </td>
                <td >
                    more data
                </td>
            </tr>
            <tr >
                <td >
                    more data
                </td>
            </tr>
        </table>
    </body>
</html>

I don’t claim that anyone should use this (there’s a good chance I won’t be releasing it, unless someone really wants me to), but I’m still quite proud of it.

»  Substance: WordPress   »  Style: Ahren Ahimsa
© Alex Mason (Axman6) 2009