/* $Id$ Part of SWI-Prolog RDF parser Author: Jan Wielemaker E-mail: jan@swi.psy.uva.nl WWW: http://www.swi.psy.uva.nl/projects/SWI-Prolog/ Copying: LGPL-2. See the file COPYING or http://www.gnu.org Copyright (C) 1990-2000 SWI, University of Amsterdam. All rights reserved. */ :- use_module(library(cgi)). :- use_module(library(sgml)). :- use_module(rdf). :- use_module(rdf_parser). :- use_module(rewrite). :- use_module(pretty_print). term_expansion(F, T) :- rew_term_expansion(F, T). goal_expansion(F, T) :- rew_goal_expansion(F, T). :- dynamic new_rdf_namespace/1. parse(Text, RDFTerm, Triples) :- parse_atom(Text, Term), ( find_rdf(Term, RDFTerm) -> true ; RDFTerm = Term ), xml_to_rdf(RDFTerm, [], Triples). find_rdf(Term, RDFTerm) :- RDFTerm = element(NS:'RDF', _, _), term_member(RDFTerm, Term), !, ( rdf_name_space(NS) -> true ; assert(rdf_parser:rdf_name_space(NS)), assert(new_rdf_namespace(NS)) ). term_member(X, X). term_member(X, Compound) :- compound(Compound), arg(_, Compound, Arg), term_member(X, Arg). % parse_atom(+Atom, -Term, +Options % % Parse and atom into a structured term parse_atom(Atom, Term) :- atom_to_memory_file(Atom, MemFile), open_memory_file(MemFile, read, Stream), new_sgml_parser(Parser, []), set_sgml_parser(Parser, dialect(xmlns)), set_sgml_parser(Parser, space(sgml)), sgml_parse(Parser, [ source(Stream), document(Term) ]), free_sgml_parser(Parser), close(Stream), free_memory_file(MemFile). /******************************* * HTML GENERATION * *******************************/ :- op(100, fx, #). :- op(110, xfx, ::). emit([]) :- !. emit([H|T]) :- !, emit(H), emit(T). emit(Fmt-Args) :- !, format(Fmt, Args), retractall(nl_done(_)). emit(#Term) :- !, #Term. emit(#Term::Content) :- !, #Term::Content. emit(Atom) :- write(Atom), retractall(nl_done(_)). #Term::Content :- Term =.. [Name|Attributes], layout(before(open, Name)), format('<~w', [Name]), attlist(Attributes), format('>', []), retractall(nl_done(_)), layout(after(open, Name)), emit(Content), end_tag(Name). #pre(Text) :- !, sgml_quote(Text, Quoted), #pre::Quoted. #box(Text) :- !, box(Text, '#e0e0e0'). #box(Text, Colour) :- !, box(Text, Colour). #Term :- Term =.. [Name|Attributes], layout(before(open, Name)), format('<~w', [Name]), attlist(Attributes), format('>', []), retractall(nl_done(_)), layout(after(open, Name)), end_tag(Name). end_tag(Name) :- blines(Name, _, o), !. end_tag(Name) :- layout(before(close, Name)), format('~w>', [Name]), retractall(nl_done(_)), layout(after(close, Name)). layout(before(open, Name)) :- blines(Name, N-_, _), !, nls(N). layout(after(open, Name)) :- blines(Name, _-N, _), !, nls(N). layout(before(close, Name)) :- blines(Name, _, N-_), !, nls(N). layout(after(close, Name)) :- blines(Name, _, _-N), !, nls(N). layout(_) :- retractall(nl_done(_)). :- dynamic nl_done/1. nls(N) :- ( nl_done(Done) -> true ; Done = 0 ), ToDo is N - Done, New is max(N, Done), retractall(nl_done(Done)), assert(nl_done(New)), do_nl(ToDo). do_nl(N) :- N > 0, !, nl, NN is N - 1, do_nl(NN). do_nl(_). blines(tr, 1-0, 0-0). blines(table, 2-1, 1-1). blines(form, 2-1, 1-1). blines(h1, 2-0, 0-1). blines(h2, 2-0, 0-2). blines(h3, 2-0, 0-2). blines(h4, 2-0, 0-2). blines(p, 2-1, o). % omitted end-tag attlist([]). attlist([Name=Value|T]) :- !, sgml_quote_value(Value, Quoted), format(' ~w=~w', [Name, Quoted]), attlist(T). attlist([Name|T]) :- format(' ~w', [Name]), attlist(T). head(Title) :- emit([ 'Content-type: text/html\n\n', '\n', '
\n', '\n'), #table(width='80%', align=center, border=6, bgcolor=Colour):: [#tr::[#td(nowrap)::[#pre(Text)]]]. /******************************* * QUOTING * *******************************/ sgml_quote_value(Value, Arg) :- atom_chars(Value, Chars), ( name_chars(Chars) -> Arg = Value ; sgml_quote_chars(Chars, Quoted), atom_chars(Arg, Quoted) ). name_chars([H|T]) :- char_type(H, alpha), all_alnum(T). all_alnum([]). all_alnum([H|T]) :- char_type(H, csymf), all_alnum(T). sgml_quote_chars(L, ['"'|T]) :- sgml_quote2(L, T, ['"']). sgml_quote2([], T, T). sgml_quote2([H|T0], List, Rest) :- sgml_quote_char(H, List, T), !, sgml_quote2(T0, T, Rest). sgml_quote2([H|T0], [H|T], Rest) :- sgml_quote2(T0, T, Rest). sgml_quote_char('<', [&, l, t, ;|T], T). sgml_quote_char('>', [&, g, t, ;|T], T). sgml_quote_char('&', [&, a, m, p, ;|T], T). sgml_quote_char('"', [&, q, u, o, t, ;|T], T). %sgml_quote_char('\'', [&, a, p, o, s, ;|T], T). sgml_quote(Text, Quoted) :- atom_chars(Text, Chars), sgml_quote2(Chars, QuotedChars, []), atom_chars(Quoted, QuotedChars). /******************************* * PAGE GENERATION * *******************************/ parsed(Time, Triples) :- length(Triples, Len), #h2::'RDF statement parsed successfully', #p::[ 'Your RDF statement has been parsed in ~2f seconds, '-[Time], 'creating ', #b::Len, ' triples. ', 'Please find the created triples in the table below.' ], ( getenv('HTTP_REFERER', Referer) -> #p::[ 'If you want to try another RDF statement, please go ', 'back to ', #a(href=Referer)::'the request form', '.' ] ; true ). rdf_table(Triples) :- maplist(triple_row, Triples, TripleRows), #p, #table(caption='RDF triples', align=center, border=2, cellpadding=3):: [ #tr::[#th::'Subject', #th::'Predicate', #th::'Object'] | TripleRows ]. triple_row(rdf(Subj, Pred, Obj), #tr::[#td::S,#td::P,#td::O]) :- cell(Subj, S), cell(Pred, P), cell(Obj, O). cell(rdf:Local, [#em::rdf, :, #b::Local]) :- !. cell(literal(X), [#b::'literal(', X, #b::')']) :- !. cell(each(X), [#b::'each(', X, #b::')']) :- !. cell(pefix(X), [#b::'prefix(', X, #b::')']) :- !. cell(NS:Local, [NS, :, #b::Local]) :- !. cell(V, [T]) :- sformat(T, '~p', [V]). /******************************* * ERRORS * *******************************/ show_errors :- getenv('ERROR_FILE', File), size_file(File, Size), Size > 0, !, read_file(File, Data), #h4::[#font(color=red):: 'The following errors occurred while processing your request'], #p, #box(Data, '#ff8c00'). show_errors. show_new_namepace :- new_rdf_namespace(NS), !, #h4::[#font(color=red)::'Warning: unofficial RDF Namespace'], #p::['It appears your RDF description uses the unofficial ', 'name space ', #b::NS, '. ', 'This name space has been added for RDF.' ]. show_new_namepace. /******************************* * COMMENT * *******************************/ comment(TextId) :- #h4::'