:- module(ag_component_correspondence, [ html_correspondence_overlay//1, % correspondence detail view, static part html_correspondences//2 % idem, dynamic part ]). :- use_module(library(option)). :- use_module(library(lists)). :- use_module(library(http/html_write)). :- use_module(library(http/http_dispatch)). :- use_module(library(semweb/rdf11)). :- use_module(library(semweb/rdf_label)). :- use_module(components(label)). :- use_module(components(graphviz)). :- use_module(library(skos/util)). :- use_module(library(amalgame/util)). :- use_module(library(amalgame/rdf_util)). html_correspondence_options(_Options) --> html([ 'include all correspondences with the same: ', input([type(checkbox), id(allsources), autocomplete(off)]), label(' source'), input([type(checkbox), id(alltargets), autocomplete(off)]), label(' target') ]). html_correspondence_buttons(Options) --> { is_list(Options), option(editmode(none), Options, none),! }, html_correspondence_buttons(nav). html_correspondence_buttons(Options) --> { is_list(Options), option(editmode(edit), Options, none),! }, html_correspondence_buttons(nav), html_correspondence_buttons(edit). html_correspondence_buttons(nav) --> html([ button([type(button), class(cancel), value(cancel), title(cancel)], 'x'), button([type(button), class(prev), value(prev), title(previous)], '<'), button([type(button), class(next), value(next), title(next)], '>') ]). html_correspondence_buttons(edit) --> % delete button only valid if nothing has changed, % submit/setall only if something has: html([ button([type(button), class([edit, notchanged, delete]), value(delete)], 'delete'), button([type(button), class([edit, changed, submit]), value(submit)], 'submit'), button([type(button), class([edit, changed, setall])], 'apply to all') ]). html_correspondence_overlay(Options) --> html(form([div([class('yui3-widget-bd')], [ div(class(options), \html_correspondence_options(Options)), div(class(buttons), \html_correspondence_buttons(Options)), div([class(concepts), id(concepts)], []) ]), div(class('yui3-widget-ft'), [ div([class(controls)], [ div(class(buttons), \html_correspondence_buttons(Options)) ]) ]) ])). %% html_correspondences(+Correspondences, +Options)// is det. % % Correspondences is a List align/3 terms, Options can be % html_correspondences([], _) --> !. html_correspondences([A|As], Options) --> html_correspondence(A, Options), html_correspondences(As, Options). fill_in_correspondence(Evidence, Relation, Comment) :- member(Method, Evidence), option(relation(Relation), Method), option(comment(Comment), Method, ''), !. fill_in_correspondence(_Evidence, undefined, ''). html_correspondence(align(Source, Target, Evidence), Options) --> { length(Evidence, EvLength), option(relations(Relations), Options, []), ( option(mode('fill-in'), Options) -> fill_in_correspondence(Evidence, Relation, Comment) ; Comment = '', Relation = undefined ) }, html([div(class('yui3-g'), [ div(class('yui3-u-1-2'), \html_resource_context(Source, Evidence)), div(class('yui3-u-1-2'), \html_resource_context(Target, Evidence)) ]), div(class([manualfixes, 'yui3-g']), [ div([class([sourcediv, 'yui3-u-1-5'])], [div([class([concepturi, sourceuri])], Source), input([type(hidden), class(original), value(Source)]), input([type(text), class([skos_ac_field]), name(source)]) ]), div([class([relations, 'yui3-u-3-5'])], \html_relations(Relations, Relation)), div([class([targetdiv, 'yui3-u-1-5'])], [div([class([concepturi, targeturi])], Target), input([type(hidden), class(original), value(Target)]), input([type(text), class([skos_ac_field]), name(target)]) ]), div(class([comment, 'yui3-u-1']), ['because: ', input([type(text), name(comment), value(Comment)]) ]) ]), div(class(evcount), [ '~w individual motivations: '-(EvLength)]), div(class(evidences), \html_evidences(Evidence, Source, Target)) ]). html_evidences([],_,_) --> !. html_evidences([E|Es],Source,Target) --> { option(method(Method), E, ''), option(graph(Graph), E, []), ( option(match(Match), E) -> format(atom(MatchAtom), ' (~2f)' , [Match]), Mt = span([class(match)], MatchAtom) ; Mt = '' ), ( option(date(Date), E) -> At = span([class(date)], [' at: ', Date]) ; At = '' ), ( option(source(MSource), E) -> format(atom(SrcAtom), ' (on: ~p' , [MSource]), Src = span([class(source)], SrcAtom) ; Src = '' ), ( option(target(MTarget), E) -> format(atom(TrgAtom), '/~p)' , [MTarget]), Trg = span([class(target)], TrgAtom) ; Trg = '' ), ( option(source_stem(SourceStem), E) -> format(atom(SStemAtom), ' (source stem: ~w)' , [SourceStem]), Ss = span([class(source_stem)], SStemAtom) ; Ss = '' ), ( option(target_stem(TargetStem), E) -> format(atom(TStemAtom), ' (target stem: ~w)' , [TargetStem]), Ts = span([class(target_stem)], TStemAtom) ; Ts = '' ), ( option(score(Score), E) -> format(atom(ScsAtom), ' (score: ~w)', [Score]), Scs = span([class(score)], ScsAtom) ; Scs = '' ), ( option(user(User), E) -> By = span([class(who)], [' by: ', \rdf_link(User)]) ; By = '' ), ( option(graph(Graph), E), atom(Graph) -> Gr = span([class(graph)], [' from: ', \rdf_link(Graph)]) ; Gr = '' ), ( option(relation(Rel), E), atom(Rel) -> Re = span([class(relation)], [' relation: ', \rdf_link(Rel)]) ; Re = '' ), ( option(comment(Comment), E) -> Cm = span([class(comment)], [' with comment: ', Comment]) ; Cm = '' ), ( option(steps((StepsS, StepsT)), E) -> St = span([class(steps)], [' source/target hier. steps: ', StepsS, '/', StepsT]) ; St = '' ) }, html(div(class(evidence), [ div(class(method), ['match: ', Method, By, Gr, Re, At, Mt, Src, Trg, Ss, Ts, Scs, Cm, St]), div(class('graph yui3-g'), [ div(class('source yui3-u-1-2'), \html_evidence_graph(Graph, Source, 'LR')), div(class('target yui3-u-1-2'), \html_evidence_graph(Graph, Target, 'RL')) ]) ])), html_evidences(Es,Source,Target). html_evidence_graph([],_,_) --> !. html_evidence_graph(Graph,Node,Layout) --> graphviz_graph(evidence_graph(Graph,Node), [shape_hook(ag_component_correspondence:evidence_shape), label_hook(ag_component_correspondence:evidence_label), graph_attributes([rankdir(Layout)])]). evidence_graph(Graph, Node, NodeTriples) :- findall(rdf(S,P,O), ( member(rdf(S,P,O), Graph), ( S == Node ; O == Node) ), NodeTriples). html_resource_context('',_) --> !. html_resource_context(URI, _Prov) --> { rdf_display_label(URI, Label), skos_all_labels(URI, Alt0), ( select(Label, Alt0, Alt) -> true ; Alt = [] ), find_other_literals(URI, Alt0, Others), resource_tree(URI, Tree), findall(R, skos_related_concept(URI, R), Related), image_examples(URI, Examples) }, html(div(class('resource-info'), [div(class(label), \html_resource(URI)), div(class(alt), \html_alt_labels(Alt)), div(class(other_literals), \html_alt_labels(Others)), \html_definition(URI), \html_scope(URI), \html_resource_tree(Tree), \html_related_list(Related), \html_image_examples(Examples) ])). find_other_literals(URI, Taboo, Others):- findall(Other, is_other_literal(URI, Taboo, Other), Others). is_other_literal(URI, Taboo, Prop:OtherLit) :- rdf(URI, Prop, Other), rdf_is_literal(Other), literal_text(Other, OtherLit), \+ member(OtherLit, Taboo). html_relations([], _) --> !. html_relations([Rel-Label|Rs], Active) --> { ( Rel == Active -> Checked = checked ; Checked = '' ) }, html(span(class(relation), [input([type(radio), name(relation), value(Rel), Checked]), ' ', label(Label) ])), html_relations(Rs, Active). html_image_examples([]) --> !. html_image_examples([E|Tail]) --> { http_link_to_id(http_thumbnail, [uri(E)], Src) }, html(div([class(example)], [img([src(Src),height(150)])] )), html_image_examples(Tail). image_examples(R, Es) :- % hack: assume non-literal examples to be image urls ... findall(E, ( rdf(R, skos:example, E), \+ rdf_is_literal(E) ), List), sort(List, Es). %% resource_tree(+Resource, -Tree) % % Tree contains the ancestors and children from Resource. resource_tree(R, Tree) :- Node = node(R, [hit], Children), ancestor_tree(Node, Tree, [], []), children(R, Children). ancestor_tree(Node, Tree, Options, DoneBefore) :- Node = node(URI,_,_), skos_parent_child(Parent, URI), \+ member(Parent, DoneBefore), ( select_option(sibblings(true), Options, Options1) -> ancestor_tree(node(Parent, [], [Node|Siblings]), Tree, Options1, [URI|DoneBefore]), children(Parent, Children), select(node(URI,_,_), Children, Siblings) ; ancestor_tree(node(Parent, [], [Node]), Tree, Options, [URI|DoneBefore]) ). ancestor_tree(Tree, Tree, _,_). children(Concept, List) :- findall(D, skos_descendant_of(Concept, D), Dlist), maplist(has_child, Dlist, List). has_child(C, node(C, [], HasChild)) :- ( skos_parent_child(C, _) -> HasChild = true ; HasChild = false ). html_alt_labels([]) --> !. html_alt_labels(Alt) --> html_label_list(Alt). html_label_list([L]) --> html_label(L). html_label_list([L|Ls]) --> html_label(L), html([', ']), html_label_list(Ls). html_label(R:L) --> html_resource(R), html(':'), html(L). html_label(L) --> html(L). html_definition(URI) --> { rdf_lang(URI, skos:definition, Txt) }, !, html_item(definition, Txt). html_definition(_) --> !. html_scope(URI) --> { rdf_lang(URI, skos:scopeNote, Txt) }, !, html_item(scope, Txt). html_scope(_) --> !. html_related_list([]) --> !. html_related_list(Rs) --> html_item(related, \html_resource_list(Rs, 3)). html_item(Type, Body) --> html(div(class(Type), [ div(class(hd), Type), div(class(bd), Body) ])). %% html_resource_list(+Resources, +Max) % % Emit HTML with a list of resources. html_resource_list(Rs, Max) --> { length(Rs, N), ( N > Max+2 -> list_limit(Rs, Max, Visible, Rest) ; Visible = Rs, Rest = [] ) }, html([ul(\html_resource_list(Visible)), \html_more_list(Rest) ]). html_resource_list([]) --> !. html_resource_list([R|Rs]) --> html(li(\html_resource(R))), html_resource_list(Rs). html_more_list([]) --> !. html_more_list(Rs) --> html(div([div(class(moretoggle), more), div(class('morelist hidden'), ul(\html_resource_list(Rs))), div(class('moretoggle hidden'), less) ])). html_resource(node(R,_,_)) --> !, rdf_link(R, [resource_format(label)]). html_resource(R) --> rdf_link(R, [resource_format(label)]). %% html_resource_tree(+Tree:node(uri,attr,children)) % % Tree to HTML. html_resource_tree(node(_,_,[])) --> !. html_resource_tree(Tree) --> html([div(class(hd), hierarchy), div(class(bd), ul(\html_tree(Tree))) ]). html_tree(node(R,[hit],Children)) --> html([li(class(hit), \html_resource(R)), ul(\html_resource_list(Children, 3)) ]). html_tree(node(R,_,Children)) --> html([li(\html_resource(R)), ul(\html_tree_children(Children)) ]). html_tree_children([]) --> !. html_tree_children([C|Cs]) --> html_tree(C), html_tree_children(Cs). evidence_shape(Resource, Shape, _Options) :- evidence_shape(Resource, Shape). %% evidence_shape(+Resource, -Shape) % % Defines graph node shape for different types of evidence % resources. evidence_shape(_@_, [shape(box), style(filled), fontsize(10)]) :- !. evidence_shape(literal(_), [shape(box), style(filled), fontsize(10)]) :- !. evidence_shape(_, [fontsize(10)]). %% evidence_label(+Resource, +Lang, +MaxLen, -Label) is det. % % Defines graph node label for different types of evidence % resources. % evidence_label(Resource, Lang, MaxLen, Label) :- rdf_display_label(Resource, Lang, Text), truncate_atom(Text, MaxLen, Label0), ( rdf_global_id(NS:_Local, Resource) -> atomic_list_concat([NS, ':', Label0], Label) ; Label = Label0 ).