Skip to content

Instantly share code, notes, and snippets.

@TheDahv
Created April 23, 2012 19:01
Show Gist options
  • Save TheDahv/2473089 to your computer and use it in GitHub Desktop.
Save TheDahv/2473089 to your computer and use it in GitHub Desktop.
FSharp Html Templating
namespace FSharpTemplate
module Template =
type HtmlElement =
| Html of HtmlElement list
| Head of HtmlElement list
| Title of string
| Body of HtmlElement list
(* id, class, children *)
| Div of string * string * HtmlElement list
(* id, class, free-content, children *)
| Para of string * string * string * HtmlElement list
let layout (content:HtmlElement list) =
Html(
[
Head(
[
Title("F# Template!")
]
);
Body(content)
]
)
let new_doc =
layout [
Div("main_div", "",
[
Para("", "", "Some body content", [])
]
)
]
let new_doc_with_text text =
layout [
Div("main_div", "",
[
Para("", "", text, [])
]
)
]
let document_text (document:HtmlElement) =
let join_words (l:string) r = l + r
let rec node_text (element:HtmlElement) =
let node_name_and_children name children =
"<" + name + ">" +
(List.fold join_words "" (List.map node_text children)) +
"</" + name + ">"
match element with
| Html children -> "<!DOCTYPE>" + node_name_and_children "html" children
| Head children -> node_name_and_children "head" children
| Title t -> "<title>" + t + "</title>"
| Body children -> node_name_and_children "body" children
| Div (id, classname, children) ->
"<div" +
(if id.Length > 0 then " id=\"" + id + "\"" else "") +
(if classname.Length > 0 then " classname=\"" + classname + "\"" else "") +
">" +
(List.fold join_words "" (List.map node_text children)) +
"</div>"
| Para (id, classname, free_content, children) ->
"<p" +
(if id.Length > 0 then " id=\"" + id + "\"" else "") +
(if classname.Length > 0 then " classname=\"" + classname + "\"" else "") +
">" +
(if free_content.Length > 0 then free_content else "") +
(List.fold join_words "" (List.map node_text children)) +
"</p>"
node_text document
[<EntryPoint>]
let main args =
let doc = if args.Length > 0 then
document_text (new_doc_with_text args.[0])
else
document_text new_doc
printfn "%s" doc
(* Return 0 for success *)
0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment