34
35:- module(html_decl,
36 [ (html_meta)/1, 37 html_no_content/1, 38
39 op(1150, fx, html_meta)
40 ]). 41:- autoload(library(apply),[maplist/3,maplist/4]). 42:- if(exists_source(library(http/http_dispatch))). 43:- autoload(library(http/http_dispatch), [http_location_by_id/2]). 44:- endif.
54
72html_meta(Spec) :-
73 throw(error(context_error(nodirective, html_meta(Spec)), _)).
74
75html_meta_decls(Var, _, _) :-
76 var(Var),
77 !,
78 instantiation_error(Var).
79html_meta_decls((A,B), (MA,MB), [MH|T]) :-
80 !,
81 html_meta_decl(A, MA, MH),
82 html_meta_decls(B, MB, T).
83html_meta_decls(A, MA, [MH]) :-
84 html_meta_decl(A, MA, MH).
85
86html_meta_decl(Head, MetaHead,
87 html_decl:html_meta_head(GenHead, Module, Head)) :-
88 functor(Head, Name, Arity),
89 functor(GenHead, Name, Arity),
90 prolog_load_context(module, Module),
91 Head =.. [Name|HArgs],
92 maplist(html_meta_decl, HArgs, MArgs),
93 MetaHead =.. [Name|MArgs].
94
95html_meta_decl(html, :) :- !.
96html_meta_decl(Meta, Meta).
97
98system:term_expansion((:- html_meta(Heads)),
99 [ (:- meta_predicate(Meta))
100 | MetaHeads
101 ]) :-
102 html_meta_decls(Heads, Meta, MetaHeads).
103
104:- multifile
105 html_meta_head/3. 106
107html_meta_colours(Head, Goal, built_in-Colours) :-
108 Head =.. [_|MArgs],
109 Goal =.. [_|Args],
110 maplist(meta_colours, MArgs, Args, Colours).
111
112meta_colours(html, HTML, Colours) :-
113 !,
114 html_colours(HTML, Colours).
115meta_colours(I, _, Colours) :-
116 integer(I), I>=0,
117 !,
118 Colours = meta(I).
119meta_colours(_, _, classify).
120
121html_meta_called(Head, Goal, Called) :-
122 Head =.. [_|MArgs],
123 Goal =.. [_|Args],
124 meta_called(MArgs, Args, Called, []).
125
126meta_called([], [], Called, Called).
127meta_called([html|MT], [A|AT], Called, Tail) :-
128 !,
129 phrase(called_by(A), Called, Tail1),
130 meta_called(MT, AT, Tail1, Tail).
131meta_called([0|MT], [A|AT], [A|CT0], CT) :-
132 !,
133 meta_called(MT, AT, CT0, CT).
134meta_called([I|MT], [A|AT], [A+I|CT0], CT) :-
135 integer(I), I>0,
136 !,
137 meta_called(MT, AT, CT0, CT).
138meta_called([_|MT], [_|AT], Called, Tail) :-
139 !,
140 meta_called(MT, AT, Called, Tail).
141
142
143
144 147
148:- multifile
149 prolog_colour:goal_colours/2,
150 prolog_colour:style/2,
151 prolog_colour:message//1,
152 prolog:called_by/2,
153 prolog:xref_update_syntax/2. 154
155prolog_colour:goal_colours(Goal, Colours) :-
156 ( html_meta_head(Goal, _Module, Head)
157 -> true
158 ; dyn_html_meta_head(Goal, _Module, Head)
159 ),
160 html_meta_colours(Head, Goal, Colours).
161prolog_colour:goal_colours(html_meta(_),
162 built_in-[meta_declarations([html])]).
163
164 165html_colours(Var, classify) :-
166 var(Var),
167 !.
168html_colours(\List, html_raw-[list-Colours]) :-
169 is_list(List),
170 !,
171 list_colours(List, Colours).
172html_colours(\_, html_call-[dcg]) :- !.
173html_colours(_:Term, built_in-[classify,Colours]) :-
174 !,
175 html_colours(Term, Colours).
176html_colours(&(Entity), functor-[entity(Entity)]) :- !.
177html_colours(List, list-ListColours) :-
178 List = [_|_],
179 !,
180 list_colours(List, ListColours).
181html_colours(Var=Spec, functor-[classify,SpecColors]) :-
182 var(Var),
183 !,
184 html_colours(Spec, SpecColors).
185html_colours(Format-Args, functor-[FormatColor,ArgsColors]) :-
186 !,
187 format_colours(Format, FormatColor),
188 format_arg_colours(Args, Format, ArgsColors).
189html_colours(Term, TermColours) :-
190 compound(Term),
191 compound_name_arguments(Term, Name, Args),
192 Name \== '.',
193 !,
194 ( Args = [One]
195 -> TermColours = html(Name)-ArgColours,
196 ( html_no_content(Name)
197 -> attr_colours(One, ArgColours)
198 ; html_colours(One, Colours),
199 ArgColours = [Colours]
200 )
201 ; Args = [AList,Content]
202 -> TermColours = html(Name)-[AColours, Colours],
203 attr_colours(AList, AColours),
204 html_colours(Content, Colours)
205 ; TermColours = error
206 ).
207html_colours(_, classify).
208
209list_colours(Var, classify) :-
210 var(Var),
211 !.
212list_colours([], []).
213list_colours([H0|T0], [H|T]) :-
214 !,
215 html_colours(H0, H),
216 list_colours(T0, T).
217list_colours(Last, Colours) :- 218 html_colours(Last, Colours).
219
220attr_colours(Var, classify) :-
221 var(Var),
222 !.
223attr_colours([], classify) :- !.
224attr_colours(Term, list-Elements) :-
225 Term = [_|_],
226 !,
227 attr_list_colours(Term, Elements).
228attr_colours(Name=Value, built_in-[html_attribute(Name), VColour]) :-
229 !,
230 attr_value_colour(Value, VColour).
231attr_colours(NS:Term, built_in-[ html_xmlns(NS),
232 html_attribute(Name)-[classify]
233 ]) :-
234 compound(Term),
235 compound_name_arity(Term, Name, 1).
236attr_colours(Term, html_attribute(Name)-[VColour]) :-
237 compound(Term),
238 compound_name_arity(Term, Name, 1),
239 !,
240 Term =.. [Name,Value],
241 attr_value_colour(Value, VColour).
242attr_colours(Name, html_attribute(Name)) :-
243 atom(Name),
244 !.
245attr_colours(Term, classify) :-
246 compound(Term),
247 compound_name_arity(Term, '.', 2),
248 !.
249attr_colours(_, error).
250
251attr_list_colours(Var, classify) :-
252 var(Var),
253 !.
254attr_list_colours([], []).
255attr_list_colours([H0|T0], [H|T]) :-
256 attr_colours(H0, H),
257 attr_list_colours(T0, T).
258
259attr_value_colour(Var, classify) :-
260 var(Var).
261attr_value_colour(location_by_id(ID), sgml_attr_function-[Colour]) :-
262 !,
263 location_id(ID, Colour).
264attr_value_colour(#(ID), sgml_attr_function-[Colour]) :-
265 !,
266 location_id(ID, Colour).
267attr_value_colour(A+B, sgml_attr_function-[CA,CB]) :-
268 !,
269 attr_value_colour(A, CA),
270 attr_value_colour(B, CB).
271attr_value_colour(encode(_), sgml_attr_function-[classify]) :- !.
272attr_value_colour(Atom, classify) :-
273 atomic(Atom),
274 !.
275attr_value_colour([_|_], classify) :- !.
276attr_value_colour(_Fmt-_Args, classify) :- !.
277attr_value_colour(Term, classify) :-
278 compound(Term),
279 compound_name_arity(Term, '.', 2),
280 !.
281attr_value_colour(_, error).
282
283location_id(ID, classify) :-
284 var(ID),
285 !.
286:- if(current_predicate(http_location_for_id/1)). 287location_id(ID, Class) :-
288 ( catch(http_location_by_id(ID, Location), _, fail)
289 -> Class = http_location_for_id(Location)
290 ; Class = http_no_location_for_id(ID)
291 ).
292:- endif. 293location_id(_, classify).
294
295format_colours(Format, format_string) :- atom(Format), !.
296format_colours(Format, format_string) :- string(Format), !.
297format_colours(_Format, type_error(text)).
298
299format_arg_colours(Args, _Format, classify) :- is_list(Args), !.
300format_arg_colours(_, _, type_error(list)).
306html_no_content(area).
307html_no_content(base).
308html_no_content(br).
309html_no_content(col).
310html_no_content(embed).
311html_no_content(hr).
312html_no_content(img).
313html_no_content(input).
314html_no_content(link).
315html_no_content(meta).
316html_no_content(param).
317html_no_content(source).
318html_no_content(track).
319html_no_content(wbr).
320
321:- op(990, xfx, :=). 322:- op(200, fy, @). 323
324prolog_colour:style(html(_), [colour(magenta4), bold(true)]).
325prolog_colour:style(entity(_), [colour(magenta4)]).
326prolog_colour:style(html_attribute(_), [colour(magenta4)]).
327prolog_colour:style(html_xmlns(_), [colour(magenta4)]).
328prolog_colour:style(format_string(_), [colour(magenta4)]).
329prolog_colour:style(sgml_attr_function, [colour(blue)]).
330prolog_colour:style(http_location_for_id(_), [bold(true)]).
331prolog_colour:style(http_no_location_for_id(_), [colour(red), bold(true)]).
332
333
334prolog_colour:message(html(Element)) -->
335 [ '~w: SGML element'-[Element] ].
336prolog_colour:message(entity(Entity)) -->
337 [ '~w: SGML entity'-[Entity] ].
338prolog_colour:message(html_attribute(Attr)) -->
339 [ '~w: SGML attribute'-[Attr] ].
340prolog_colour:message(sgml_attr_function) -->
341 [ 'SGML Attribute function'-[] ].
342prolog_colour:message(http_location_for_id(Location)) -->
343 [ 'ID resolves to ~w'-[Location] ].
344prolog_colour:message(http_no_location_for_id(ID)) -->
345 [ '~w: no such ID'-[ID] ].
346
347
348 351
352:- dynamic dyn_html_meta_head/3 as volatile. 353
354prolog:xref_update_syntax((:- html_meta(Decls)), Module) :-
355 dyn_meta_heads(Decls, Module).
356
357dyn_meta_heads((A,B), Module) =>
358 dyn_meta_heads(A, Module),
359 dyn_meta_heads(B, Module).
360dyn_meta_heads(QHead, Module) =>
361 strip_module(Module:QHead, M, Head),
362 most_general_goal(Head, Gen),
363 retractall(dyn_html_meta_head(Gen, M, _)),
364 asserta(dyn_html_meta_head(Gen, M, Head)).
365
370
371prolog:called_by(Goal, Called) :-
372 ( html_meta_head(Goal, _Module, Head)
373 -> true
374 ; dyn_html_meta_head(Goal, _Module, Head)
375 ),
376 html_meta_called(Head, Goal, Called).
377
378called_by(Term) -->
379 called_by(Term, _).
380
381called_by(Var, _) -->
382 { var(Var) },
383 !,
384 [].
385called_by(\G, M) -->
386 !,
387 ( { is_list(G) }
388 -> called_by(G, M)
389 ; {atom(M)}
390 -> [(M:G)+2]
391 ; [G+2]
392 ).
393called_by([], _) -->
394 !,
395 [].
396called_by([H|T], M) -->
397 !,
398 called_by(H, M),
399 called_by(T, M).
400called_by(M:Term, _) -->
401 !,
402 ( {atom(M)}
403 -> called_by(Term, M)
404 ; []
405 ).
406called_by(Var=Term, M) -->
407 { var(Var) },
408 called_by(Term, M).
409called_by(Term, M) -->
410 { compound(Term),
411 !,
412 Term =.. [_|Args]
413 },
414 called_by(Args, M).
415called_by(_, _) -->
416 []
HTML emitter analysis and IDE support
This library supports declaring DCG rules that process HTML terms. It supports the cross-referencer as well as syntax highlighting that is based on library(prolog_colour). */