1/* Part of SWI-Prolog 2 3 Author: Jan Wielemaker 4 E-mail: J.Wielemaker@vu.nl 5 WWW: http://www.swi-prolog.org 6 Copyright (c) 2007-2018, University of Amsterdam 7 CWI, Amsterdam 8 All rights reserved. 9 10 Redistribution and use in source and binary forms, with or without 11 modification, are permitted provided that the following conditions 12 are met: 13 14 1. Redistributions of source code must retain the above copyright 15 notice, this list of conditions and the following disclaimer. 16 17 2. Redistributions in binary form must reproduce the above copyright 18 notice, this list of conditions and the following disclaimer in 19 the documentation and/or other materials provided with the 20 distribution. 21 22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 POSSIBILITY OF SUCH DAMAGE. 34*/ 35 36:- module(doc_util, 37 [ insert_alias/2, % +Path, -Aliased 38 expand_alias/2, % +Aliased, -Path 39 ensure_slash_end/2, % +Dir, -DirSlash 40 atom_pi/2, % +Atom, -PI 41 atom_to_object/2, % +Atom, -Object 42 normalise_white_space//1 % -Text 43 ]). 44:- use_module(library(dcg/basics)). 45 46/** <module> PlDoc utilities 47 48@author Jan Wielemaker 49*/ 50 51 /******************************* 52 * PATH ALIAS PROCESSING * 53 *******************************/ 54 55%! insert_alias(+Path0, -Path) is det. 56% 57% Translate a native path to an aliased path. Path aliases are 58% defined by path_alias/2. Aliased paths are re-translated into 59% native form using expand_alias/2. 60 61insert_alias(Path0, Path) :- 62 path_alias(Alias, Prefix), 63 atom_concat(Prefix, PostFix, Path0), 64 !, 65 atom_concat(Alias, PostFix, Path). 66insert_alias(Path, Path). 67 68 69%! expand_alias(+Path0, -Path) is det. 70% 71% Translate an aliased path to a native path. 72 73expand_alias(Path0, Path) :- 74 path_alias(Alias, Prefix), 75 atom_concat(Alias, Postfix, Path0), 76 !, 77 atom_concat(Prefix, Postfix, Path). 78expand_alias(Path, Path). 79 80 81%! path_alias(?Alias, ?Path) is nondet. 82% 83% True if Alias: is an alias for Path. This is used to rewrite 84% paths below the SWI-Prolog home to give them shorter and fixed 85% names. 86 87path_alias('/_SWI_/', Dir) :- 88 current_prolog_flag(home, Dir0), 89 ensure_slash_end(Dir0, Dir). 90path_alias('/_CWD_/', Dir) :- 91 working_directory(Dir0, Dir0), 92 ensure_slash_end(Dir0, Dir). 93 94 95 /******************************* 96 * MISC PATH OPERATIONS * 97 *******************************/ 98 99%! ensure_slash_end(+Dir, -DirSlash) is det. 100% 101% Ensure Dir ends with a /. 102 103ensure_slash_end(Dir, Dir) :- 104 sub_atom(Dir, _, _, 0, /), 105 !. 106ensure_slash_end(Dir0, Dir) :- 107 atom_concat(Dir0, /, Dir). 108 109 /******************************* 110 * PREDICATES * 111 *******************************/ 112 113%! atom_pi(+Atom, -PI) is det. 114% 115% Translate an external predicate indicator representated as an 116% atom into a predicate indicator term. If Atom contains 117% <module>:, PI is qialified. If no arity is provided it is a term 118% Name/_, i.e., with unbound arity. 119 120 121atom_pi(Atom, Module:PI) :- 122 atomic_list_concat([Module, PIAtom], :, Atom), 123 Module \== '', 124 forall(sub_atom(Module, _,1,_,C), char_type(C,alnum)), 125 !, 126 atom_pi2(PIAtom, PI). 127atom_pi(Atom, PI) :- 128 atom_pi2(Atom, PI). 129 130atom_pi2(Atom, Name//Arity) :- 131 sub_atom(Atom, B, _, A, //), 132 sub_atom(Atom, _, A, 0, ArityA), 133 atom_number(ArityA, Arity), 134 sub_atom(Atom, 0, B, _, Name), 135 Name \== '', 136 !. 137atom_pi2(Atom, Name/Arity) :- 138 sub_atom(Atom, B, _, A, /), 139 sub_atom(Atom, _, A, 0, ArityA), 140 atom_number(ArityA, Arity), 141 !, 142 sub_atom(Atom, 0, B, _, Name). 143atom_pi2(Name, Name/_). 144 145%! atom_to_object(+Atom, -PredicateIndicator) is semidet. 146% 147% If Atom is `Name/Arity', decompose to Name and Arity. No errors. 148 149atom_to_object(Atom, Object) :- 150 atom(Atom), 151 atom_concat('f-', Atom0, Atom), 152 !, 153 PI = _/_, % avoid qualified and DCG 154 atom_pi(Atom0, PI), 155 Object = f(PI). 156atom_to_object(Atom, Object) :- 157 atom(Atom), 158 atom_pi(Atom, PI), 159 ground(PI), 160 !, 161 ( PI = Name/Arity, 162 integer(Arity), 163 atom_concat('f-', FuncName, Name) 164 -> Object = f(FuncName/Arity) 165 ; Object = PI 166 ). 167atom_to_object(Atom, c(Function)) :- 168 atom(Atom), 169 ( sub_atom(Atom, 0, _, _, 'PL_') 170 -> true 171 ; sub_atom(Atom, 0, _, _, 'S') 172 ), 173 sub_atom(Atom, B, _, _, '('), 174 !, 175 sub_atom(Atom, 0, B, _, Function). 176 177%! normalise_white_space(-Text)// is det. 178% 179% Text is input after deleting leading and trailing white space 180% and mapping all internal white space to a single space. 181 182normalise_white_space(Text) --> 183 blanks, 184 normalise_white_space2(Text). 185 186normalise_white_space2(Text) --> 187 non_ws(Text, Tail), 188 blanks, 189 ( eos 190 -> { Tail = [] } 191 ; { Tail = [0'\s|T2] }, 192 normalise_white_space2(T2) 193 ). 194 195%! non_ws(-Text, ?Tail) is det. 196% 197% True if the difference list Text-Tail is the sequence of 198% non-white-space characters. 199 200non_ws([H|T0], T) --> 201 [H], 202 { \+ code_type(H, space) }, 203 !, 204 non_ws(T0, T). 205non_ws(T, T) --> 206 []