View source with raw comments or as raw
    1/*  Part of ClioPatria SeRQL and SPARQL server
    2
    3    Author:        Jan Wielemaker
    4    E-mail:        J.Wielemaker@cs.vu.nl
    5    WWW:           http://www.swi-prolog.org
    6    Copyright (C): 2010, University of Amsterdam,
    7		   VU University Amsterdam
    8
    9    This program is free software; you can redistribute it and/or
   10    modify it under the terms of the GNU General Public License
   11    as published by the Free Software Foundation; either version 2
   12    of the License, or (at your option) any later version.
   13
   14    This program is distributed in the hope that it will be useful,
   15    but WITHOUT ANY WARRANTY; without even the implied warranty of
   16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17    GNU General Public License for more details.
   18
   19    You should have received a copy of the GNU General Public
   20    License along with this library; if not, write to the Free Software
   21    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   22
   23    As a special exception, if you link this library with other files,
   24    compiled with a Free Software compiler, to produce an executable, this
   25    library does not by itself cause the resulting executable to be covered
   26    by the GNU General Public License. This exception does not however
   27    invalidate any other reasons why the executable file might be covered by
   28    the GNU General Public License.
   29*/
   30
   31:- module(rdf_label,
   32	  [ rdf_label/2,		% +Resource, -Literal
   33	    rdf_display_label/2,	% +Resource, -Text
   34	    rdf_display_label/3,	% +Resource, +Lang, -Text
   35	    literal_text/2,		% +Literal, -Text
   36	    truncate_atom/3,		% +Atom, -MaxLen -Text
   37	    label_property/1		% ?Property
   38	  ]).   39:- use_module(library(error)).   40:- use_module(library(sgml_write)).   41:- use_module(library(semweb/rdf_db)).   42:- use_module(user(preferences)).

Generate labels for RDF objects

This library deals with a common problem in RDF applications: show labels for resources and display literals. There is no clear-cut answer to this problem because there are too many options. Think of e.g., language preferences, producing summaries, desired rdfs/owl/... reasoning. Therefore, this library provides the required APIs a default implementation and hooks that allow for dealing with the above mentioned issues. */

   56:- multifile
   57	label_property/1,		% ?Resource
   58	label_hook/2,			% +Resource, -Literal
   59	display_label_hook/3.		% +Resource, ?Lang, -Label
   60
   61:- rdf_meta
   62	rdf_label(r,-),
   63	rdf_display_label(r,-),
   64	rdf_display_label(r,?,-),
   65	label_property(r).   66
   67					% this dependency is not ideal ...
   68:- rdf_register_ns(foaf, 'http://xmlns.com/foaf/0.1/').
 label_property(?Property) is nondet
True if Property is used to represent labels. The default definition defines SKOS (prefLabel, altLabel, DC (title) and rdfs:label. This predicate is defined as multifile.
   76label_property(skos:prefLabel).
   77label_property(foaf:name).
   78label_property(dc:title).
   79label_property(rdfs:label).
   80label_property(skos:altLabel).
 rdf_label(+R, -Label:literal) is nondet
Label is a label for R. This predicate first calls the hook label_hook/2. If this hook fails it produces all property-values for the properties defined by label_property/1 that have a literal value.
   90rdf_label(R, Label) :-
   91	(   label_hook(R, Label)
   92	*-> true
   93	;   label_property(P),
   94	    rdf_has(R, P, Label),
   95	    rdf_is_literal(Label)
   96	).
 rdf_display_label(+R, -Label:atom) is det
Provide a label for R in the user's default language. This is the same as rdf_display_label(R, _, Label).
See also
- user_preference/2
  106rdf_display_label(R, Label) :-
  107	rdf_display_label(R, _, Label).
 rdf_display_label(+R, ?Lang, -Label:atom) is det
Label is the preferred label to display the resource R in the language Lang. As a last resort, this predicates creates a label from the URI R. In that case, Lang is unified with url.
  116rdf_display_label(R, Lang, Label) :-
  117	rdf_real_label(R, Lang, Label), !.
  118rdf_display_label(Resource, url, Label) :-
  119	(   after_char(Resource, '#', Local), Local \= ''
  120	->  Label = Local
  121	;   after_char(Resource, '/', Local), Local \= ''
  122	->  Label = Local
  123	;   Label = Resource
  124	).
  125
  126
  127rdf_real_label(R, Lang, Label) :-
  128	display_label_hook(R, Lang, Label), !.
  129rdf_real_label(R, Lang, Label) :-
  130	rdf_is_resource(R),
  131	(   nonvar(Lang), % try fast option first:
  132	    rdf_label(R, literal(lang(Lang, Literal)))
  133	->  true
  134	;   nonvar(Lang),
  135	    % warning: BT over next call is quite expensive when R has labels in many languages:
  136	    rdf_label(R, Literal),
  137	    Literal = literal(lang(L, _)),
  138	    lang_matches(L, Lang)
  139	->  true
  140	;   user_preference(user:lang, literal(Lang)), % try fast option first:
  141	    rdf_label(R, literal(lang(Lang, Literal)))
  142	->  true
  143	;   user_preference(user:lang, literal(Lang)),
  144	    % warning: BT over next call is quite expensive when R has labels in many languages:
  145	    rdf_label(R, Literal),
  146	    Literal = literal(lang(L, _)),
  147	    lang_matches(L, Lang)
  148	->  true
  149	;   rdf_label(R, Literal),
  150	    literal_lang(Literal, Lang),
  151	    var(Lang)
  152	->  true
  153	;   rdf_label(R, Literal),
  154	    literal_lang(Literal, Lang)
  155	->  true
  156	), !,
  157	literal_text(Literal, Label).
  158rdf_real_label(BNode, Lang, Label) :-
  159	rdf_has(BNode, rdf:value, Value),
  160	rdf_real_label(Value, Lang, Label0), !,
  161	format(atom(Label), '[~a..]', Label0).
  162rdf_real_label(Literal, Lang, Label) :-
  163	rdf_is_literal(Literal), !,
  164	literal_lang(Literal, Lang),
  165	literal_text(Literal, Label).
  166
  167after_char(Atom, Char, Rest) :-
  168	State = last(-),
  169	(   sub_atom(Atom, _, _, L, Char),
  170	    nb_setarg(1, State, L),
  171	    fail
  172	;   arg(1, State, L),
  173	    L \== (-)
  174	),
  175	sub_atom(Atom, _, L, 0, Rest).
  176
  177literal_lang(literal(Lang0, _), Lang) :- !,
  178	Lang = Lang0.
  179literal_lang(_, _).
 literal_text(+Object, -Text:atom) is semidet
Text is the textual content of Object. Fails if Object is not an RDF literal (term literal(Value)). If Object is an XMLLiteral, Text is unified with the XML-text.
Errors
- instantiation_error if Object is not ground
  189literal_text(X, _) :-
  190	\+ ground(X), !, !,
  191	instantiation_error(X).
  192literal_text(literal(L), Text) :- !,
  193	literal_text(L, Text).
  194literal_text(type(Type, Value), Text) :- !,
  195	typed_text(Type, Value, Text).
  196literal_text(lang(_, Text), Text) :- !.
  197literal_text(Text, Text).
  198
  199:- rdf_meta
  200	typed_text(r, +, -).  201
  202typed_text(_, Value, Text) :-
  203	atom(Value), !,
  204	Text = Value.
  205typed_text(rdfs:'XMLLiteral', Value, Text) :-
  206	xml_is_dom(Value), !,
  207	with_output_to(atom(Text),
  208		       xml_write(current_output, Value,
  209				 [ header(false),
  210				   layout(false)
  211				 ])).
  212typed_text(_, Value, Text) :-
  213	format(atom(Text), '~w', [Value]).
 truncate_atom(+Atom, +MaxLen, -Truncated) is det
If Atom is longer than MaxLen, truncate it. If MaxLen is inf, Truncated is unified with Atom.
  220truncate_atom(Atom, inf, All) :- !,
  221	All = Atom.
  222truncate_atom(Atom, MaxLen, Truncated) :-
  223	atom_length(Atom, Len),
  224	(   Len =< MaxLen
  225	->  Truncated = Atom
  226	;   TLen is max(3, MaxLen-4),
  227	    sub_atom(Atom, 0, TLen, _, S0),
  228	    atom_concat(S0, ' ...', Truncated)
  229	).
  230
  231		 /*******************************
  232		 *	      SANDBOX		*
  233		 *******************************/
  234
  235:- multifile
  236	sandbox:safe_primitive/1.  237
  238sandbox:safe_primitive(rdf_label:typed_text(_,_,_))