:- module(tag_matcher, []). :- use_module(library(http/http_dispatch)). :- use_module(library(http/http_parameters)). :- use_module(library(http/html_write)). :- use_module(library(http/html_head)). :- use_module(library(http/http_json)). :- use_module(library(http/json)). :- use_module(library(http/json_convert)). :- use_module(library(semweb/rdf_db)). :- use_module(library(semweb/rdfs)). :- use_module(library(tag_match)). :- use_module(components(label)). /** Tag matcher This module provides a web service for fuzzy matching of two strings (e.g. tags). @author Michiel Hildebrand */ :- http_handler(root(tagmatch), http_tag_match_page, []). :- http_handler(root(api/tagmatch), http_tag_match_api, []). :- rdf_meta scheme_type(r,-). %% http_tag_match_page(+Request) % % HTTP handler to create a simple web page with a form to enter % and match two tags. http_tag_match_page(Request) :- http_parameters(Request, [ t1(Tag1, [optional(true), description('a tag')]), t2(Tag2, [optional(true), description('another tag')]) ]), ( (var(Tag1); var(Tag2)) -> true ; tag_match(Tag1, Tag2, MatchType, T1Data, T2Data) -> true ; MatchType = false ), reply_html_page(cliopatria(default), [title('Tag matcher'), style(['h2 { border-bottom: 1px solid #CCC;}', '.tag-input-line, .tag-data-line { margin-bottom: 5px; } ', 'table {border: 1px solid #CCC; }', 'td { padding: 2px 10px; }' ]) ], [h2('tag matcher'), div(class('tag-input'), form(action(location_by_id(http_tag_match_page)), [ \html_tag_input(1, Tag1), \html_tag_input(2, Tag2), input([type(submit), value(match)]), ' examples: ', \html_match_examples ])), div(class('tag-match'), \html_tag_match(MatchType)), div(class('tag-data'), [ \html_tag_data(1, T1Data), \html_tag_data(2, T2Data) ]) ]). html_tag_input(N, Tag) --> { ( var(Tag) -> Txt = '' ; Txt = Tag ) }, html(div(class('tag-input-line'), [ label(['tag ', N, ': ']), input([type(text), name(t+N), value(Txt)]) ])). html_tag_data(_, TagData) --> { var(TagData) ; TagData = [] }, !. html_tag_data(N, TagData) --> html(div(class('tag-data-line'), [ label(['tag ', N]), table(\tag_data_rows(TagData)) ])). tag_data_rows([]) --> !. tag_data_rows([K=V|T]) --> html(tr([td(\data_cell(K)), td(\data_cell(V))])), tag_data_rows(T). data_cell(R) --> { atom(R), rdf_subject(R) }, !, rdf_link(R). data_cell(R) --> html(R). html_tag_match(Type) --> { var(Type) }, !. html_tag_match(false) --> html(h3('no match found')). html_tag_match(Type) --> html(h3(['match: ', Type])). html_match_examples --> { findall(e(N,T1,T2), example(N,T1,T2), Es) }, html_example_links(Es). html_example_links([E]) --> example_link(E). html_example_links([E|Es]) --> example_link(E), html(' | '), html_example_links(Es). example_link(e(Name, Tag1, Tag2)) --> { http_location_by_id(http_tag_match_page, Link) }, html(a(href(Link+'?t1='+Tag1+'&t2='+Tag2), Name)). example(exact, verhagen, verhagen). example(stemming, auto, autos). example(synonym, auto, wagen). example(specific, labrador, hond). example(specific2, 'amsterdam-oost', amsterdam). example(generic, paal, amsterdammertje). %% http_tag_match_api(+Request) % % HTTP handler to determine the match between two tags. http_tag_match_api(Request) :- http_parameters(Request, [ t1(Tag1, [description('a tag')]), t2(Tag2, [description('another tag')]) ]), ( tag_match(Tag1, Tag2, MatchType, T1Data, T2Data) -> true ; MatchType = @false, T1Data = [], T2Data = [] ), reply_json(json([t1=json([tag=Tag1|T1Data]), t2=json([tag=Tag2|T2Data]), match=MatchType ])).