/* Term to Html converter. use node_html(Nodes, Html) to convert the prolog structure to an HTML string. Each element type can take children and some can take attributes. Text content must be wrapped in an s(_) term to identify it as different to other content. Examples; 1. A paragraph with some text. p(s("This is the text")). 2. A div with class and two paragraphs. div([class("my-div")], [ p(s("This is the first paragraph.")), p(s("This is the second paragraph.")) ]). Not every attribute type or HTML type has been mapped, but they are easy to map below. - el_type(ElementTerm, Definition) maps the elements, there are plenty of examples. - el_attribute(AttributeTerm, StringName, Value) maps attribute types. */ % % HTML Elements % el_unify(A,A). % Section Elements el_type(html(C), node("html", C)). el_type(body(C), node("body", C)). el_type(head(C), node("head", C)). el_type(header(C), node("header", C)). el_type(main(C), node("main", C)). el_type(footer(C), node("footer", C)). el_type(nav(C), node("nav", C)). el_type(article(C), node("article", C)). el_type(section(C), node("section", C)). el_type(section(A, C), attr("section", C, A)). % Format elements el_type(div(C), node("div", C)). el_type(div(A, C), node("div", C, A)). el_type(span(C), node("span", C)). el_type(span(A, C), node("span", C, A)). el_type(hr, attr_only("hr", [])). el_type(br, attr_only("br", [])). el_type(p(C), node("p", C)). el_type(pre(C), node("pre", C)). el_type(code(C), node("code", C)). el_type(blockquote(C), node("blockquote", C)). % Header elements el_type(title(C), node("title", C)). el_type(script(C), node("script", C)). el_type(script(A, C), attr("script", C, A)). el_type(style(C), node("style", C)). el_type(link(A), attr_only("link", A)). el_type(meta(A), attr_only("meta", A)). % Text elements el_type(h1(C), node("h1", C)). el_type(h2(C), node("h2", C)). el_type(h3(C), node("h3", C)). el_type(a(A,C), attr("a", C, A)). % List elements el_type(ol(C), node("ol", C)). el_type(ul(C), node("ul", C)). el_type(li(C), node("li", C)). el_type(dl(C), node("dl", C)). el_type(dt(C), node("dt", C)). el_type(dd(C), node("dd", C)). % String types el_type(s(C), any(C)). % Valid HTML Attributes el_attribute(href(V), "href", V). el_attribute(class(V), "class", V). el_attribute(rel(V), "rel", V). el_attribute(title(V), "title", V). el_attribute(id(V), "id", V). el_attribute(name(V), "name", V). el_attribute(content(V), "content", V). % % Node to HTML predicates. % % Convert a node tree to a HTML string. node_html(RootNode, Html) :- el(RootNode, Html, []). % An HTML elememt el(Node, A, B) :- el_type(Node, Type), el_typed(Type, A, B). % An element categorised by type. el_typed(node(Text, C), A, B) :- el_node(Text, [], C, A, B). el_typed(attr(Text, C, Attr), A, B) :- el_node(Text, Attr, C, A, B). el_typed(attr_only(Text, Attr), A, B) :- el_attr_only_node(Text, Attr, A, B). el_typed(any(C), A, B) :- el_any(C, A, B). % Generate a single HTML element node. el_node(Node, Attributes, Children, [<|A], B) :- el_any(Node, A, C), el_attributes(Attributes, C, D), el_unify(D, [>|E]), el_children(Children, E, F), el_unify(F, [<, /|G]), el_any(Node, G, H), el_unify(H, [>|B]). el_attr_only_node(Node, Attributes, [<|A], B) :- el_any(Node, A, C), el_attributes(Attributes, C, D), el_unify(D, [' ',/,>|B]). % Write any attributes to the HTML node. el_attributes([], A, A). el_attributes([Att|Next], A, B) :- el_unify(A, [' '|C]), el_attribute(Att, AttName, Value), el_any(AttName, C, D), el_unify(D, ['="'|E]), el_any(Value, E, F), el_unify(F, ['"'|G]), el_attributes(Next, G, B). % Generate the children for an HTML node. el_children(s(S), A, B) :- el_any(S, A, B). el_children([], A, A). el_children([El|Next], A, B) :- el(El, A, C), el_children(Next, C, B). % Write the contents to the output directly el_any([], A, A). el_any([C|T], [C|A], B) :- el_any(T, A, B).