[Caml-list] [ANN] HTCaML / CaSS

4 views
Skip to first unread message

Thomas Gazagnaire

unread,
Nov 23, 2010, 8:06:25 AM11/23/10
to caml...@yquem.inria.fr
I am happy to announce the first official release of HTCaML[1] and
CaSS[2], two small libraries which make the writing of static web pages
easy in OCaml.

HTCaML enables the embedding of XHTML fragments in your OCaml program
(the EDSL translates directly to Xmlm) using quotations. It also allows
you to auto-generate boilerplate XHTML fragments from type definitions.
In the same way, CaSS enables the embedding of CSS fragments in your
OCaml program using quotations.

A quick example:

module Box = struct
type t = { title: string; date: string; contents: Html.t } with html
let css fg bg = <:css<
color: $fg$;
background-color: $bg$;
$Css.rounded$;
.title { color: $bg$; background-color: $fg$; }
>>
end

let my_html boxes = Html.to_string <:html<
<html>
<body>
<div class="boxes">
$list:List.map Box.html_of_t boxes$
</div>
</body>
</html>
>>

let my_css = Css.to_string <:css<
.boxes { $Box.css <:css< blue >> <:css< white >> $ }
>>

You can find a quick introduction to HTCaML (and maybe soon to CaSS) on
the mirage blog[3].

Cheers,
Thomas

[1] https://github.com/samoht/htcaml
[2] https://github.com/samoht/cass
[3] http://www.openmirage.org/blog/introduction-to-htcaml

_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

Gerd Stolpmann

unread,
Nov 23, 2010, 8:22:58 AM11/23/10
to Thomas Gazagnaire, caml...@yquem.inria.fr
Have you seen that there is a preprocessor for PXP that allows you to
embed XML in ocaml?

http://projects.camlcity.org/projects/dl/pxp-1.2.1/doc/manual/html/ref/Intro_preprocessor.html

I'm happily using this for dynamic web pages. The syntax is more
light-weight, though, e.g. you write

<div> [ ... ]

instead of <div>...</div>, and there is a distinction in the syntax
between node and list of nodes, e.g.

<div> list

but

<div> [ node1 node2 ... ]

Gerd


--
------------------------------------------------------------
Gerd Stolpmann, Bad Nauheimer Str.3, 64289 Darmstadt,Germany
ge...@gerd-stolpmann.de http://www.gerd-stolpmann.de
Phone: +49-6151-153855 Fax: +49-6151-997714
------------------------------------------------------------

Thomas Gazagnaire

unread,
Nov 23, 2010, 9:01:36 AM11/23/10
to Gerd Stolpmann, caml...@yquem.inria.fr
> Have you seen that there is a preprocessor for PXP that allows you to
> embed XML in ocaml?
>
> http://projects.camlcity.org/projects/dl/pxp-1.2.1/doc/manual/html/ref/Intro_preprocessor.html
>

No, I didn't know about that. And there is also a syntax extension in
Eliom to do the same kind of things.

However, the two things I am really happy with HTCaML (and apparently it
is not possible to do the same thing in PXP nor Eliom) are :
i) you can easily mix auto-generated and hand-crafted code to create
XHTML fragments (no more tedious conversion functions); and
ii) you can write in the same part of your file (ie. in the same module)
the css and xhtml generator for a given type definition. That means that
you can do web-programming as you are used to : think about type
definitions first, and then write your code to reason by induction on
these defintions.

for example, you can have:

type foo = (* some random type *)
let html_of_foo : Html.t = (* some random code of type Html.t = (`a
Xml.frag as `a) Xmlm.frag list *)
let foo_css = (* some random, possibly nested, CSS *)

and :

type bar = { foo : foo; complex types } with html
let bar_css = <:css< .foo { $foo_css$; ... } >>

In the later case, you don't have to write manually the code for
html_of_bar as it will be done automatically by HTCaML, by looking at
the structure of bar; and it will pick your own definition of
html_of_foo. Also, nested declarations in bar_css will be automatically
unrolled to generate valid CSS fragments.

> I'm happily using this for dynamic web pages. The syntax is more
> light-weight, though, e.g. you write
>

I don't really call this dynamic web pages, but yea, that's the same
idea :-)

--
Thomas


> <div> [ ... ]
>
> instead of <div>...</div>, and there is a distinction in the syntax
> between node and list of nodes, e.g.
>
> <div> list
>
> but
>
> <div> [ node1 node2 ... ]
>
> Gerd
>
> Am Dienstag, den 23.11.2010, 14:05 +0100 schrieb Thomas Gazagnaire:

Thomas Gazagnaire

unread,
Nov 23, 2010, 9:05:07 AM11/23/10
to Gerd Stolpmann, caml...@yquem.inria.fr
> let html_of_foo : Html.t = (* some random code of type Html.t = (`a
Xml.frag as `a) Xmlm.frag list *)

Sorry, I mean : let html_of_foo : foo -> Html.t = ...

Gerd Stolpmann

unread,
Nov 23, 2010, 10:25:28 AM11/23/10
to Thomas Gazagnaire, caml...@yquem.inria.fr
Am Dienstag, den 23.11.2010, 15:01 +0100 schrieb Thomas Gazagnaire:
> > Have you seen that there is a preprocessor for PXP that allows you to
> > embed XML in ocaml?
> >
> > http://projects.camlcity.org/projects/dl/pxp-1.2.1/doc/manual/html/ref/Intro_preprocessor.html
> >
>
> No, I didn't know about that. And there is also a syntax extension in
> Eliom to do the same kind of things.
>
> However, the two things I am really happy with HTCaML (and apparently it
> is not possible to do the same thing in PXP nor Eliom) are :
> i) you can easily mix auto-generated and hand-crafted code to create
> XHTML fragments (no more tedious conversion functions); and

Don't know whether this is good or bad - having everything as XML means
you can also type-check the emitted XML (e.g. against the DTD). It's
only at runtime, but might still be helpful.

In PXP you would have to use a custom XML writer to merge in
hand-crafted HTML.

Btw, there are some subtle differences between real XHTML (with an
XML-ish content type) and "HTML that looks like XML". For example, in
real XML SCRIPT or STYLE sections need to be quoted like other data
sections whereas HTML sees these as exceptions to the normal rules (e.g.
<script>if (a &lt; b) { ... }</script> in XML and <script>if (a<b)
{...}</script> in HTML). This is something that makes mixing in HTML
error-prone.

> ii) you can write in the same part of your file (ie. in the same module)
> the css and xhtml generator for a given type definition. That means that
> you can do web-programming as you are used to : think about type
> definitions first, and then write your code to reason by induction on
> these defintions.
>
> for example, you can have:
>
> type foo = (* some random type *)
> let html_of_foo : Html.t = (* some random code of type Html.t = (`a
> Xml.frag as `a) Xmlm.frag list *)
> let foo_css = (* some random, possibly nested, CSS *)
>
> and :
>
> type bar = { foo : foo; complex types } with html
> let bar_css = <:css< .foo { $foo_css$; ... } >>
>
> In the later case, you don't have to write manually the code for
> html_of_bar as it will be done automatically by HTCaML, by looking at
> the structure of bar; and it will pick your own definition of
> html_of_foo. Also, nested declarations in bar_css will be automatically
> unrolled to generate valid CSS fragments.

Interesting idea - data-centric HTML generation.

Gerd

--
------------------------------------------------------------
Gerd Stolpmann, Bad Nauheimer Str.3, 64289 Darmstadt,Germany
ge...@gerd-stolpmann.de http://www.gerd-stolpmann.de
Phone: +49-6151-153855 Fax: +49-6151-997714
------------------------------------------------------------

_______________________________________________

Reply all
Reply to author
Forward
0 new messages