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) 2006-2023, University of Amsterdam 7 VU University Amsterdam 8 CWI, Amsterdam 9 SWI-Prolog Solutions b.v. 10 All rights reserved. 11 12 Redistribution and use in source and binary forms, with or without 13 modification, are permitted provided that the following conditions 14 are met: 15 16 1. Redistributions of source code must retain the above copyright 17 notice, this list of conditions and the following disclaimer. 18 19 2. Redistributions in binary form must reproduce the above copyright 20 notice, this list of conditions and the following disclaimer in 21 the documentation and/or other materials provided with the 22 distribution. 23 24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 27 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 28 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 29 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 30 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 34 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 POSSIBILITY OF SUCH DAMAGE. 36*/ 37 38:- module(pldoc_html, 39 [ doc_for_file/2, % +FileSpec, +Options 40 doc_write_html/3, % +Stream, +Title, +Term 41 doc_for_wiki_file/2, % +FileSpec, +Options 42 % Support doc_index 43 doc_page_dom/3, % +Title, +Body, -DOM 44 print_html_head/1, % +Stream 45 predref//1, % +PI // 46 predref//2, % +PI, Options // 47 nopredref//1, % +PI // 48 module_info/3, % +File, +Options0, -Options 49 doc_hide_private/3, % +Doc0, -Doc, +Options 50 edit_button//2, % +File, +Options, // 51 source_button//2, % +File, +Options, // 52 zoom_button//2, % +File, +Options, // 53 pred_edit_button//2, % +PredInd, +Options, // 54 object_edit_button//2, % +Obj, +Options, // 55 object_source_button//2, % +Obj, +Options, // 56 doc_resources//1, % +Options 57 ensure_doc_objects/1, % +File 58 % Support other backends 59 doc_file_objects/5, % +FSpec, -File, -Objs, -FileOpts, +Opts 60 existing_linked_file/2, % +FileSpec, -Path 61 unquote_filespec/2, % +FileSpec, -Unquoted 62 doc_tag_title/2, % +Tag, -Title 63 mode_anchor_name/2, % +Mode, -Anchor 64 pred_anchor_name/3, % +Head, -PI, -Anchor 65 private/2, % +Obj, +Options 66 (multifile)/2, % +Obj, +Options 67 is_pi/1, % @Term 68 is_op_type/2, % +Atom, ?Type 69 % Output routines 70 file//1, % +File, // 71 file//2, % +File, +Options, // 72 include//3, % +File, +Type, +Options // 73 tags//1, % +Tags, // 74 term//3, % +Text, +Term, +Bindings, // 75 file_header//2, % +File, +Options, // 76 flagref//1, % +Flag 77 objects//2, % +Objects, +Options, // 78 object_ref//2, % +Object, +Options, // 79 object_name//2, % +Object, +Object 80 object_href/2, % +Object, -URL 81 object_tree//3, % +Tree, +Current, +Options 82 object_page//2, % +Object, +Options, // 83 object_page_header//2, % +File, +Options, // 84 object_synopsis//2, % +Object, +Options, // 85 object_footer//2, % +Object, +Options, // 86 object_page_footer//2, % +Object, +Options, // 87 cite//1 % +Citations 88 ]). 89% Get HTTP server infrastructure when available 90:- if(exists_source(library(http/http_dispatch))). 91:- use_module(library(http/http_dispatch)). 92:- use_module(library(http/http_wrapper)). 93:- use_module(library(http/jquery)). 94 95pldoc_server(true). 96:- else. 97 98:- multifile 99 http:location/3. 100 101httplocation(pldoc_resource, '/pldoc/res', []). 102 103pldoc_server(false). 104:- endif. 105 106:- use_module(library(lists)). 107:- use_module(library(option)). 108:- use_module(library(uri)). 109:- use_module(library(readutil)). 110:- use_module(library(http/html_write)). 111:- use_module(library(http/http_path)). 112:- use_module(library(http/html_head)). 113:- use_module(library(http/term_html)). 114:- use_module(library(debug)). 115:- use_module(library(apply)). 116:- use_module(library(pairs)). 117:- use_module(library(filesex)). 118:- use_module(doc_process). 119:- use_module(doc_man). 120:- use_module(doc_modes). 121:- use_module(doc_wiki). 122:- use_module(doc_search). 123:- use_module(doc_index). 124:- use_module(doc_util). 125:- use_module(library(solution_sequences)). 126:- use_module(library(error)). 127:- use_module(library(occurs)). 128:- use_module(library(prolog_source)). 129:- use_module(library(prolog_xref)). 130 131:- include(hooks).
143:- public 144 args//1, % Called from \Term output created 145 pred_dt//3, % by the wiki renderer 146 section//2, 147 tag//2. 148 149 150:- predicate_options(doc_for_wiki_file/2, 2, 151 [ edit(boolean) 152 ]). 153:- predicate_options(doc_hide_private/3, 3, 154 [module(atom), public(list), public_only(boolean)]). 155:- predicate_options(edit_button//2, 2, 156 [ edit(boolean) 157 ]). 158:- predicate_options(file//2, 2, 159 [ label(any), 160 absolute_path(atom), 161 href(atom), 162 map_extension(list), 163 files(list), 164 edit_handler(atom) 165 ]). 166:- predicate_options(file_header//2, 2, 167 [ edit(boolean), 168 files(list), 169 public_only(boolean) 170 ]). 171:- predicate_options(include//3, 3, 172 [ absolute_path(atom), 173 class(atom), 174 files(list), 175 href(atom), 176 label(any), 177 map_extension(list) 178 ]). 179:- predicate_options(object_edit_button//2, 2, 180 [ edit(boolean), 181 pass_to(pred_edit_button//2, 2) 182 ]). 183:- predicate_options(object_page//2, 2, 184 [ for(any), 185 header(boolean), 186 links(boolean), 187 no_manual(boolean), 188 try_manual(boolean), 189 search_in(oneof([all,app,man])), 190 search_match(oneof([name,summary])), 191 search_options(boolean) 192 ]). 193:- predicate_options(object_ref//2, 2, 194 [ files(list), 195 qualify(boolean), 196 style(oneof([number,title,number_title])), 197 secref_style(oneof([number,title,number_title])) 198 ]). 199:- predicate_options(object_synopsis//2, 2, 200 [ href(atom) 201 ]). 202:- predicate_options(pred_dt//3, 3, 203 [ edit(boolean) 204 ]). 205:- predicate_options(pred_edit_button//2, 2, 206 [ edit(boolean) 207 ]). 208:- predicate_options(predref//2, 2, 209 [ files(list), 210 prefer(oneof([manual,app])), 211 pass_to(object_ref/4, 2) 212 ]). 213:- predicate_options(private/2, 2, 214 [ module(atom), 215 public(list) 216 ]). 217:- predicate_options(source_button//2, 2, 218 [ files(list) 219 ]). 220 221 222 /******************************* 223 * RESOURCES * 224 *******************************/ 225 226:- if(pldoc_server(true)). 227:- html_resource(pldoc_css, 228 [ virtual(true), 229 requires([ pldoc_resource('pldoc.css') 230 ]) 231 ]). 232:- html_resource(pldoc_resource('pldoc.js'), 233 [ requires([ jquery 234 ]) 235 ]). 236:- html_resource(pldoc_js, 237 [ virtual(true), 238 requires([ pldoc_resource('pldoc.js') 239 ]) 240 ]). 241:- html_resource(pldoc, 242 [ virtual(true), 243 requires([ pldoc_css, 244 pldoc_js 245 ]) 246 ]). 247:- else. 248:- html_resource(pldoc_css, [virtual(true)]). 249:- html_resource(pldoc_resource('pldoc.js'), [virtual(true)]). 250:- html_resource(pldoc_js, [virtual(true)]). 251:- html_resource(pldoc, [virtual(true)]). 252:- endif. 253 254 255 /******************************* 256 * FILE PROCESSING * 257 *******************************/
true
(default), only emit documentation for
exported predicates.true
, provide edit buttons. Default, these buttons
are suppressed.278doc_for_file(FileSpec, Options) :- 279 doc_file_objects(FileSpec, File, Objects, FileOptions, Options), 280 doc_file_title(File, Title, FileOptions, Options), 281 doc_write_page( 282 pldoc(file(File, Title)), 283 title(Title), 284 \prolog_file(File, Objects, FileOptions, Options), 285 Options). 286 287doc_file_title(_, Title, _, Options) :- 288 option(title(Title), Options), 289 !. 290doc_file_title(File, Title, FileOptions, _) :- 291 memberchk(file(Title0, _Comment), FileOptions), 292 !, 293 file_base_name(File, Base), 294 atomic_list_concat([Base, ' -- ', Title0], Title). 295doc_file_title(File, Title, _, _) :- 296 file_base_name(File, Title). 297 298:- html_meta doc_write_page( , , , ). 299 300doc_write_page(Style, Head, Body, Options) :- 301 option(files(_), Options), 302 !, 303 phrase(page(Style, Head, Body), HTML), 304 print_html(HTML). 305doc_write_page(Style, Head, Body, _) :- 306 reply_html_page(Style, Head, Body). 307 308 309prolog_file(File, Objects, FileOptions, Options) --> 310 { b_setval(pldoc_file, File), % TBD: delete? 311 file_directory_name(File, Dir) 312 }, 313 html([ \doc_resources(Options), 314 \doc_links(Dir, FileOptions), 315 \file_header(File, FileOptions) 316 | \objects(Objects, FileOptions) 317 ]), 318 undocumented(File, Objects, FileOptions).
doc_files.pl
. A bit hacky ...325doc_resources(Options) --> 326 { option(resource_directory(ResDir), Options), 327 nb_current(pldoc_output, OutputFile), 328 !, 329 directory_file_path(ResDir, 'pldoc.css', Res), 330 relative_file_name(Res, OutputFile, Ref) 331 }, 332 html_requires(Ref). 333doc_resources(Options) --> 334 { option(html_resources(Resoures), Options, pldoc) 335 }, 336 html_requires(Resoures).
file(Title:string, Comment:string)
module(Module:atom)
list(predicate_indicator)
Objects contains
doc(PI:predicate_indicator, File:Line, Comment)
We distinguish three different states for FileSpec:
365doc_file_objects(FileSpec, File, Objects, FileOptions, Options) :- 366 xref_current_source(FileSpec), 367 xref_option(FileSpec, comments(collect)), 368 !, 369 File = FileSpec, 370 findall(Object, xref_doc_object(File, Object), Objects0), 371 reply_file_objects(File, Objects0, Objects, FileOptions, Options). 372doc_file_objects(FileSpec, File, Objects, FileOptions, Options) :- 373 absolute_file_name(FileSpec, File, 374 [ file_type(prolog), 375 access(read) 376 ]), 377 source_file(File), 378 !, 379 ensure_doc_objects(File), 380 Pos = File:Line, 381 findall(Line-doc(Obj,Pos,Comment), 382 doc_comment(Obj, Pos, _, Comment), Pairs), 383 sort(Pairs, Pairs1), % remove duplicates 384 keysort(Pairs1, ByLine), 385 pairs_values(ByLine, Objs0), 386 reply_file_objects(File, Objs0, Objects, FileOptions, Options). 387doc_file_objects(FileSpec, File, Objects, FileOptions, Options) :- 388 absolute_file_name(FileSpec, File, 389 [ file_type(prolog), 390 access(read) 391 ]), 392 xref_source(File, [silent(true)]), 393 findall(Object, xref_doc_object(File, Object), Objects0), 394 reply_file_objects(File, Objects0, Objects, FileOptions, Options). 395 396 397reply_file_objects(File, Objs0, Objects, FileOptions, Options) :- 398 module_info(File, ModuleOptions, Options), 399 file_info(Objs0, Objs1, FileOptions, ModuleOptions), 400 doc_hide_private(Objs1, ObjectsSelf, ModuleOptions), 401 include_reexported(ObjectsSelf, Objects1, File, FileOptions), 402 remove_doc_duplicates(Objects1, Objects, []). 403 404remove_doc_duplicates([], [], _). 405remove_doc_duplicates([H|T0], [H|T], Seen) :- 406 H = doc(_, _, Comment), 407 \+ memberchk(Comment, Seen), 408 !, 409 remove_doc_duplicates(T0, T, [Comment|Seen]). 410remove_doc_duplicates([_|T0], T, Seen) :- 411 remove_doc_duplicates(T0, T, Seen). 412 413include_reexported(SelfObjects, Objects, File, Options) :- 414 option(include_reexported(true), Options), 415 option(module(Module), Options), 416 option(public(Exports), Options), 417 select_undocumented(Exports, Module, SelfObjects, Undoc), 418 re_exported_doc(Undoc, File, Module, REObjs, _), 419 REObjs \== [], 420 !, 421 append(SelfObjects, REObjs, Objects). 422include_reexported(Objects, Objects, _, _).
427xref_doc_object(File, doc(M:module(Title),File:0,Comment)) :- 428 xref_comment(File, Title, Comment), 429 xref_module(File, M). 430xref_doc_object(File, doc(M:Name/Arity,File:0,Comment)) :- 431 xref_comment(File, Head, _Summary, Comment), 432 xref_module(File, Module), 433 strip_module(Module:Head, M, Plain), 434 functor(Plain, Name, Arity).
445:- dynamic 446 no_comments/2. 447 448ensure_doc_objects(File) :- 449 source_file(File), 450 !, 451 ( doc_file_has_comments(File) 452 -> true 453 ; no_comments(File, TimeChecked), 454 time_file(File, TimeChecked) 455 -> true 456 ; xref_source(File, [silent(true), comments(store)]), 457 retractall(no_comments(File, _)), 458 ( doc_file_has_comments(File) 459 -> true 460 ; time_file(File, TimeChecked), 461 assertz(no_comments(File, TimeChecked)) 462 ) 463 ). 464ensure_doc_objects(File) :- 465 xref_source(File, [silent(true)]).
module(Name)
, public(Exports)
to OtherOptions if
File is a module file.472module_info(File, [module(Module), public(Exports)|Options], Options) :- 473 module_property(Module, file(File)), 474 !, 475 module_property(Module, exports(Exports)). 476module_info(File, [module(Module), public(Exports)|Options], Options) :- 477 xref_module(File, Module), 478 !, 479 findall(PI, xref_exported_pi(File, PI), Exports). 480module_info(_, Options, Options). 481 482xref_exported_pi(Src, Name/Arity) :- 483 xref_exported(Src, Head), 484 functor(Head, Name, Arity).
490doc_hide_private(Objs, Objs, Options) :- 491 option(public_only(false), Options, true), 492 !. 493doc_hide_private(Objs0, Objs, Options) :- 494 hide_private(Objs0, Objs, Options). 495 496hide_private([], [], _). 497hide_private([H|T0], T, Options) :- 498 obj(H, Obj), 499 private(Obj, Options), 500 !, 501 hide_private(T0, T, Options). 502hide_private([H|T0], [H|T], Options) :- 503 hide_private(T0, T, Options).
511obj(doc(Obj0, _Pos, _Summary), Obj) :- 512 !, 513 ( Obj0 = [Obj|_] 514 -> true 515 ; Obj = Obj0 516 ). 517obj(Obj0, Obj) :- 518 ( Obj0 = [Obj|_] 519 -> true 520 ; Obj = Obj0 521 ).
530:- multifile 531 prolog:doc_is_public_object/1. 532 533private(Object, _Options) :- 534 prolog:doc_is_public_object(Object), !, fail. 535private(Module:PI, Options) :- 536 multifile(Module:PI, Options), !, fail. 537private(Module:PI, Options) :- 538 public(Module:PI, Options), !, fail. 539private(Module:PI, Options) :- 540 option(module(Module), Options), 541 option(public(Public), Options), 542 !, 543 \+ ( member(PI2, Public), 544 eq_pi(PI, PI2) 545 ). 546private(Module:PI, _Options) :- 547 module_property(Module, file(_)), % A loaded module 548 !, 549 module_property(Module, exports(Exports)), 550 \+ ( member(PI2, Exports), 551 eq_pi(PI, PI2) 552 ). 553private(Module:PI, _Options) :- 554 \+ (pi_to_head(PI, Head), 555 xref_exported(Source, Head), 556 xref_module(Source, Module)).
567multifile(Obj, _Options) :-
568 strip_module(user:Obj, Module, PI),
569 pi_to_head(PI, Head),
570 ( predicate_property(Module:Head, multifile)
571 ; xref_module(Source, Module),
572 xref_defined(Source, Head, multifile(_Line))
573 ),
574 !.
580public(Obj, _Options) :- 581 strip_module(user:Obj, Module, PI), 582 pi_to_head(PI, Head), 583 ( predicate_property(Module:Head, public) 584 ; xref_module(Source, Module), 585 xref_defined(Source, Head, public(_Line)) 586 ), 587 !. 588 589pi_to_head(Var, _) :- 590 var(Var), !, fail. 591pi_to_head(Name/Arity, Term) :- 592 functor(Term, Name, Arity). 593pi_to_head(Name//DCGArity, Term) :- 594 Arity is DCGArity+2, 595 functor(Term, Name, Arity).
file(Title, Comment)
to OtherOptions if available.601file_info(Comments, RestComments, [file(Title, Comment)|Opts], Opts) :- 602 select(doc(_:module(Title),_,Comment), Comments, RestComments), 603 !. 604file_info(Comments, Comments, Opts, Opts).
611file_header(File, Options) --> 612 { memberchk(file(Title, Comment), Options), 613 !, 614 file_base_name(File, Base) 615 }, 616 file_title([Base, ' -- ', Title], File, Options), 617 { is_structured_comment(Comment, Prefixes), 618 string_codes(Comment, Codes), 619 indented_lines(Codes, Prefixes, Lines), 620 section_comment_header(Lines, _Header, Lines1), 621 wiki_lines_to_dom(Lines1, [], DOM) 622 }, 623 html(DOM). 624file_header(File, Options) --> 625 { file_base_name(File, Base) 626 }, 627 file_title([Base], File, Options).
634file_title(Title, File, Options) --> 635 prolog:doc_file_title(Title, File, Options), 636 !. 637file_title(Title, File, Options) --> 638 { file_base_name(File, Base) 639 }, 640 html(h1(class(file), 641 [ span(style('float:right'), 642 [ \reload_button(File, Base, Options), 643 \zoom_button(Base, Options), 644 \source_button(Base, Options), 645 \edit_button(File, Options) 646 ]) 647 | Title 648 ])).
658reload_button(File, _Base, Options) --> 659 { \+ source_file(File), 660 \+ option(files(_), Options) 661 }, 662 !, 663 html(span(class(file_anot), '[not loaded]')). 664reload_button(_File, Base, Options) --> 665 { option(edit(true), Options), 666 !, 667 option(public_only(Public), Options, true) 668 }, 669 html(a(href(Base+[reload(true), public_only(Public)]), 670 img([ class(action), 671 alt('Reload'), 672 title('Make & Reload'), 673 src(location_by_id(pldoc_resource)+'reload.png') 674 ]))). 675reload_button(_, _, _) --> [].
683edit_button(File, Options) --> 684 { option(edit(true), Options) 685 }, 686 !, 687 html(a([ onClick('HTTPrequest(\'' + 688 location_by_id(pldoc_edit) + [file(File)] + 689 '\')') 690 ], 691 img([ class(action), 692 alt(edit), 693 title('Edit file'), 694 src(location_by_id(pldoc_resource)+'edit.png') 695 ]))). 696edit_button(_, _) --> 697 [].
704zoom_button(_, Options) --> 705 { option(files(_Map), Options) }, 706 !. % generating files 707zoom_button(Base, Options) --> 708 { ( option(public_only(true), Options, true) 709 -> Zoom = 'public.png', 710 Alt = 'Public', 711 Title = 'Click to include private', 712 PublicOnly = false 713 ; Zoom = 'private.png', 714 Alt = 'All predicates', 715 Title = 'Click to show exports only', 716 PublicOnly = true 717 ) 718 }, 719 html(a(href(Base+[public_only(PublicOnly)]), 720 img([ class(action), 721 alt(Alt), 722 title(Title), 723 src(location_by_id(pldoc_resource)+Zoom) 724 ]))).
731source_button(_File, Options) --> 732 { option(files(_Map), Options) }, 733 !. % generating files 734source_button(File, _Options) --> 735 { ( is_absolute_file_name(File) 736 -> doc_file_href(File, HREF0) 737 ; HREF0 = File 738 ) 739 }, 740 html(a(href(HREF0+[show(src)]), 741 img([ class(action), 742 alt('Show source'), 743 title('Show source'), 744 src(location_by_id(pldoc_resource)+'source.png') 745 ]))).
true
, provide a navitation tree.755objects(Objects, Options) --> 756 { option(navtree(true), Options), 757 !, 758 objects_nav_tree(Objects, Tree) 759 }, 760 html([ div(class(navtree), 761 div(class(navwindow), 762 \nav_tree(Tree, Objects, Options))), 763 div(class(navcontent), 764 \objects_nt(Objects, Options)) 765 ]). 766objects(Objects, Options) --> 767 objects_nt(Objects, Options). 768 769objects_nt(Objects, Options) --> 770 objects(Objects, [body], Options). 771 772objects([], Mode, _) --> 773 pop_mode(body, Mode, _). 774objects([Obj|T], Mode, Options) --> 775 object(Obj, Mode, Mode1, Options), 776 objects(T, Mode1, Options).
787object(doc(Obj,Pos,Comment), Mode0, Mode, Options) --> 788 !, 789 object(Obj, [Pos-Comment], Mode0, Mode, [scope(file)|Options]). 790object(Obj, Mode0, Mode, Options) --> 791 { findall(Pos-Comment, 792 doc_comment(Obj, Pos, _Summary, Comment), 793 Pairs) 794 }, 795 !, 796 { b_setval(pldoc_object, Obj) }, 797 object(Obj, Pairs, Mode0, Mode, Options). 798 799object(Obj, Pairs, Mode0, Mode, Options) --> 800 { is_pi(Obj), 801 !, 802 maplist(pred_dom(Obj, Options), Pairs, DOMS), 803 append(DOMS, DOM) 804 }, 805 need_mode(dl, Mode0, Mode), 806 html(DOM). 807object([Obj|_Same], Pairs, Mode0, Mode, Options) --> 808 !, 809 object(Obj, Pairs, Mode0, Mode, Options). 810object(Obj, _Pairs, Mode, Mode, _Options) --> 811 { debug(pldoc, 'Skipped ~p', [Obj]) }, 812 []. 813 814pred_dom(Obj, Options, Pos-Comment, DOM) :- 815 is_structured_comment(Comment, Prefixes), 816 string_codes(Comment, Codes), 817 indented_lines(Codes, Prefixes, Lines), 818 strip_module(user:Obj, Module, _), 819 process_modes(Lines, Module, Pos, Modes, Args, Lines1), 820 ( private(Obj, Options) 821 -> Class = privdef % private definition 822 ; multifile(Obj, Options) 823 -> ( option(scope(file), Options) 824 -> ( more_doc(Obj, Pos) 825 -> Class = multidef(object(Obj)) 826 ; Class = multidef 827 ) 828 ; Class = multidef(file((Pos))) 829 ) 830 ; public(Obj, Options) 831 -> Class = publicdef % :- public definition 832 ; Class = pubdef % exported definition 833 ), 834 ( Obj = Module:_ 835 -> POptions = [module(Module)|Options] 836 ; POptions = Options 837 ), 838 Pos = File:Line, 839 DTOptions = [file(File),line(Line)|POptions], 840 DOM = [\pred_dt(Modes, Class, DTOptions), dd(class=defbody, DOM1)], 841 wiki_lines_to_dom(Lines1, Args, DOM0), 842 strip_leading_par(DOM0, DOM1). 843 844more_doc(Obj, File:_) :- 845 doc_comment(Obj, File2:_, _, _), 846 File2 \== File, 847 !.
856need_mode(Mode, Stack, Stack) --> 857 { Stack = [Mode|_] }, 858 !, 859 []. 860need_mode(Mode, Stack, Rest) --> 861 { memberchk(Mode, Stack) 862 }, 863 !, 864 pop_mode(Mode, Stack, Rest). 865need_mode(Mode, Stack, [Mode|Stack]) --> 866 !, 867 html_begin(Mode). 868 869pop_mode(Mode, Stack, Stack) --> 870 { Stack = [Mode|_] }, 871 !, 872 []. 873pop_mode(Mode, [H|Rest0], Rest) --> 874 html_end(H), 875 pop_mode(Mode, Rest0, Rest).
881undocumented(File, Objs, Options) --> 882 { memberchk(module(Module), Options), 883 memberchk(public(Exports), Options), 884 select_undocumented(Exports, Module, Objs, Undoc), 885 re_exported_doc(Undoc, File, Module, REObjs, ReallyUnDoc) 886 }, 887 !, 888 re_exported_doc(REObjs, Options), 889 undocumented(ReallyUnDoc, Options). 890undocumented(_, _, _) --> 891 []. 892 893re_exported_doc([], _) --> !. 894re_exported_doc(Objs, Options) --> 895 reexport_header(Objs, Options), 896 objects(Objs, Options). 897 898reexport_header(_, Options) --> 899 { option(reexport_header(true), Options, true) 900 }, 901 !, 902 html([ h2(class(wiki), 'Re-exported predicates'), 903 p([ "The following predicates are exported from this file \c 904 while their implementation is defined in imported modules \c 905 or non-module files loaded by this module." 906 ]) 907 ]). 908reexport_header(_, _) --> 909 []. 910 911undocumented([], _) --> !. 912undocumented(UnDoc, Options) --> 913 html([ h2(class(undoc), 'Undocumented predicates'), 914 p(['The following predicates are exported, but not ', 915 'or incorrectly documented.' 916 ]), 917 dl(class(undoc), 918 \undocumented_predicates(UnDoc, Options)) 919 ]). 920 921 922undocumented_predicates([], _) --> 923 []. 924undocumented_predicates([H|T], Options) --> 925 undocumented_pred(H, Options), 926 undocumented_predicates(T, Options). 927 928undocumented_pred(Name/Arity, Options) --> 929 { functor(Head, Name, Arity) }, 930 html(dt(class=undoc, \pred_mode(Head, [], _, Options))). 931 932select_undocumented([], _, _, []). 933select_undocumented([PI|T0], M, Objs, [PI|T]) :- 934 is_pi(PI), 935 \+ in_doc(M:PI, Objs), 936 !, 937 select_undocumented(T0, M, Objs, T). 938select_undocumented([_|T0], M, Objs, T) :- 939 select_undocumented(T0, M, Objs, T). 940 941in_doc(PI, Objs) :- 942 member(doc(O,_,_), Objs), 943 ( is_list(O) 944 -> member(O2, O), 945 eq_pi(PI, O2) 946 ; eq_pi(PI, O) 947 ).
954eq_pi(PI, PI) :- !. 955eq_pi(M:PI1, M:PI2) :- 956 atom(M), 957 !, 958 eq_pi(PI1, PI2). 959eq_pi(Name/A, Name//DCGA) :- 960 A =:= DCGA+2, 961 !. 962eq_pi(Name//DCGA, Name/A) :- 963 A =:= DCGA+2.
969is_pi(Var) :- 970 var(Var), 971 !, 972 fail. 973is_pi(_:PI) :- 974 !, 975 is_pi(PI). 976is_pi(_/_). 977is_pi(_//_).
983re_exported_doc([], _, _, [], []). 984re_exported_doc([PI|T0], File, Module, [doc(Orig:PI,Pos,Comment)|ObjT], UnDoc) :- 985 pi_to_head(PI, Head), 986 ( predicate_property(Module:Head, imported_from(Orig)) 987 -> true 988 ; predicate_property(Module:Head, exported) 989 -> Orig = Module 990 ; xref_defined(File, Head, imported(File2)), 991 ensure_doc_objects(File2), 992 xref_module(File2, Orig) 993 ), 994 doc_comment(Orig:PI, Pos, _, Comment), 995 !, 996 re_exported_doc(T0, File, Module, ObjT, UnDoc). 997re_exported_doc([PI|T0], File, Module, REObj, [PI|UnDoc]) :- 998 re_exported_doc(T0, File, Module, REObj, UnDoc). 999 1000 1001 /******************************* 1002 * SINGLE OBJECT PAGE * 1003 *******************************/
1013object_page(Obj, Options) --> 1014 prolog:doc_object_page(Obj, Options), 1015 !, 1016 object_page_footer(Obj, Options). 1017object_page(Obj, Options) --> 1018 { doc_comment(Obj, File:_Line, _Summary, _Comment) 1019 }, 1020 !, 1021 ( { \+ ( doc_comment(Obj, File2:_, _, _), 1022 File2 \== File ) 1023 } 1024 -> html([ \html_requires(pldoc), 1025 \object_page_header(File, Options), 1026 \object_synopsis(Obj, []), 1027 \objects([Obj], Options) 1028 ]) 1029 ; html([ \html_requires(pldoc), 1030 \object_page_header(-, Options), 1031 \objects([Obj], [synopsis(true)|Options]) 1032 ]) 1033 ), 1034 object_page_footer(Obj, Options). 1035object_page(M:Name/Arity, Options) --> % specified module, but public 1036 { functor(Head, Name, Arity), 1037 ( predicate_property(M:Head, exported) 1038 -> module_property(M, class(library)) 1039 ; \+ predicate_property(M:Head, defined) 1040 ) 1041 }, 1042 prolog:doc_object_page(Name/Arity, Options), 1043 !, 1044 object_page_footer(Name/Arity, Options). 1045 1046object_page_header(File, Options) --> 1047 prolog:doc_page_header(file(File), Options), 1048 !. 1049object_page_header(File, Options) --> 1050 { option(header(true), Options, true) }, 1051 !, 1052 html(div(class(navhdr), 1053 [ div(class(jump), \file_link(File)), 1054 div(class(search), \search_form(Options)), 1055 br(clear(right)) 1056 ])). 1057object_page_header(_, _) --> []. 1058 1059file_link(-) --> 1060 !, 1061 places_menu(-). 1062file_link(File) --> 1063 { file_directory_name(File, Dir) 1064 }, 1065 places_menu(Dir), 1066 html([ div(a(href(location_by_id(pldoc_doc)+File), File)) 1067 ]).
1074object_footer(Obj, Options) --> 1075 prolog:doc_object_footer(Obj, Options), 1076 !. 1077object_footer(_, _) --> [].
1085object_page_footer(Obj, Options) --> 1086 prolog:doc_object_page_footer(Obj, Options), 1087 !. 1088object_page_footer(_, _) --> [].
1102object_synopsis(Name/Arity, _) --> 1103 { functor(Head, Name, Arity), 1104 predicate_property(system:Head, built_in) 1105 }, 1106 synopsis([span(class(builtin), 'built-in')]). 1107object_synopsis(Name/Arity, Options) --> 1108 !, 1109 object_synopsis(_:Name/Arity, Options). 1110object_synopsis(M:Name/Arity, Options) --> 1111 { functor(Head, Name, Arity), 1112 ( option(source(Spec), Options) 1113 -> absolute_file_name(Spec, File, 1114 [ access(read), 1115 file_type(prolog), 1116 file_errors(fail) 1117 ]) 1118 ; predicate_property(M:Head, exported), 1119 \+ predicate_property(M:Head, imported_from(_)), 1120 module_property(M, file(File)), 1121 file_name_on_path(File, Spec) 1122 ), 1123 !, 1124 unquote_filespec(Spec, Unquoted), 1125 ( predicate_property(Head, autoload(FileBase)), 1126 file_name_extension(FileBase, _Ext, File) 1127 -> Extra = [span(class(autoload), '(can be autoloaded)')] 1128 ; Extra = [] 1129 ) 1130 }, 1131 ( { option(href(HREF), Options) } 1132 -> synopsis([code([':- use_module(',a(href(HREF), '~q'-[Unquoted]),').'])|Extra]) 1133 ; synopsis([code(':- use_module(~q).'-[Unquoted])|Extra]) 1134 ). 1135object_synopsis(Name//Arity, Options) --> 1136 !, 1137 { DCGArity is Arity+2 }, 1138 object_synopsis(Name/DCGArity, Options). 1139object_synopsis(Module:Name//Arity, Options) --> 1140 !, 1141 { DCGArity is Arity+2 }, 1142 object_synopsis(Module:Name/DCGArity, Options). 1143object_synopsis(f(_/_), _) --> 1144 synopsis(span(class(function), 1145 [ 'Arithmetic function (see ', 1146 \object_ref(is/2, []), 1147 ')' 1148 ])). 1149object_synopsis(c(Func), _) --> 1150 { sub_atom(Func, 0, _, _, 'PL_') 1151 ; sub_atom(Func, 0, _, _, 'S') 1152 }, 1153 !, 1154 synopsis([span(class(cfunc), 'C-language interface function')]). 1155object_synopsis(_, _) --> []. 1156 1157synopsis(Text) --> 1158 html(div(class(synopsis), 1159 [ span(class('synopsis-hdr'), 'Availability:') 1160 | Text 1161 ])).
1168unquote_filespec(Spec, Unquoted) :- 1169 compound(Spec), 1170 Spec =.. [Alias,Path], 1171 atom(Path), 1172 atomic_list_concat(Parts, /, Path), 1173 maplist(need_no_quotes, Parts), 1174 !, 1175 parts_to_path(Parts, UnquotedPath), 1176 Unquoted =.. [Alias, UnquotedPath]. 1177unquote_filespec(Spec, Spec). 1178 1179need_no_quotes(Atom) :- 1180 format(atom(A), '~q', [Atom]), 1181 \+ sub_atom(A, 0, _, _, '\''). 1182 1183parts_to_path([One], One) :- !. 1184parts_to_path(List, More/T) :- 1185 ( append(H, [T], List) 1186 -> parts_to_path(H, More) 1187 ). 1188 1189 1190 /******************************* 1191 * PRINT * 1192 *******************************/
1198doc_write_html(Out, Title, Doc) :-
1199 doc_page_dom(Title, Doc, DOM),
1200 phrase(html(DOM), Tokens),
1201 print_html_head(Out),
1202 print_html(Out, Tokens).
1209doc_page_dom(Title, Body, DOM) :-
1210 DOM = html([ head([ title(Title),
1211 link([ rel(stylesheet),
1212 type('text/css'),
1213 href(location_by_id(pldoc_resource)+'pldoc.css')
1214 ]),
1215 script([ src(location_by_id(pldoc_resource)+'pldoc.js'),
1216 type('text/javascript')
1217 ], [])
1218 ]),
1219 body(Body)
1220 ]).
DOCTYPE
line.1226print_html_head(Out) :- 1227 format(Out, 1228 '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" \c 1229 "http://www.w3.org/TR/html4/strict.dtd">~n', []). 1230 1231% Rendering rules 1232% 1233% These rules translate \-terms produced by wiki.pl
1241tags(Tags) -->
1242 html(dl(class=tags, Tags)).
tag(Name, Values)
terms produced by doc_wiki.pl
.1248tag(Tag, Values) --> 1249 { doc_tag_title(Tag, Title), 1250 atom_concat('keyword-', Tag, Class) 1251 }, 1252 html([ dt(class=Class, Title), 1253 \tag_values(Values, Class) 1254 ]). 1255 1256tag_values([], _) --> 1257 []. 1258tag_values([H|T], Class) --> 1259 html(dd(class=Class, ['- '|H])), 1260 tag_values(T, Class).
1267doc_tag_title(Tag, Title) :- 1268 tag_title(Tag, Title), 1269 !. 1270doc_tag_title(Tag, Tag). 1271 1272tag_title(compat, 'Compatibility'). 1273tag_title(tbd, 'To be done'). 1274tag_title(see, 'See also'). 1275tag_title(error, 'Errors'). 1276tag_title(since, 'Since').
args(List)
created by doc_wiki.pl
. Params is a
list of arg(Name, Descr)
.1283args(Params) --> 1284 html([ dt(class=tag, 'Arguments:'), 1285 dd(table(class=arglist, 1286 \arg_list(Params))) 1287 ]). 1288 1289arg_list([]) --> 1290 []. 1291arg_list([H|T]) --> 1292 argument(H), 1293 arg_list(T). 1294 1295argument(arg(Name,Descr)) --> 1296 html(tr([td(var(Name)), td(class=argdescr, ['- '|Descr])])). 1297 1298 1299 /******************************* 1300 * NAVIGATION TREE * 1301 *******************************/
node(Object, Children)
.1308objects_nav_tree(Objects, Tree) :- 1309 maplist(object_nav_tree, Objects, Trees), 1310 union_trees(Trees, Tree0), 1311 remove_unique_root(Tree0, Tree). 1312 Obj, Tree) (:- 1314 Node = node(directory(Dir), FileNodes), 1315 FileNode = node(file(File), Siblings), 1316 doc_comment(Obj, File:_Line, _Summary, _Comment), 1317 !, 1318 file_directory_name(File, Dir), 1319 sibling_file_nodes(Dir, FileNodes0), 1320 selectchk(node(file(File),[]), FileNodes0, FileNode, FileNodes), 1321 findall(Sibling, doc_comment(Sibling, File:_, _, _), Siblings0), 1322 delete(Siblings0, _:module(_), Siblings1), 1323 doc_hide_private(Siblings1, Siblings2, []), 1324 flatten(Siblings2, Siblings), % a comment may describe objects 1325 embed_directories(Node, Tree). 1326 1327sibling_file_nodes(Dir, Nodes) :- 1328 findall(node(file(File), []), 1329 ( source_file(File), 1330 file_directory_name(File, Dir) 1331 ), 1332 Nodes). 1333 1334embed_directories(Node, Tree) :- 1335 Node = node(file(File), _), 1336 !, 1337 file_directory_name(File, Dir), 1338 Super = node(directory(Dir), [Node]), 1339 embed_directories(Super, Tree). 1340embed_directories(Node, Tree) :- 1341 Node = node(directory(Dir), _), 1342 file_directory_name(Dir, SuperDir), 1343 SuperDir \== Dir, 1344 !, 1345 Super = node(directory(SuperDir), [Node]), 1346 embed_directories(Super, Tree). 1347embed_directories(Tree, Tree). 1348 1349 1350union_trees([Tree], Tree) :- !. 1351union_trees([T1,T2|Trees], Tree) :- 1352 merge_trees(T1, T2, M1), 1353 union_trees([M1|Trees], Tree). 1354 1355merge_trees(node(R, Ch1), node(R, Ch2), node(R, Ch)) :- 1356 merge_nodes(Ch1, Ch2, Ch). 1357 1358merge_nodes([], Ch, Ch) :- !. 1359merge_nodes(Ch, [], Ch) :- !. 1360merge_nodes([node(Root, Ch1)|T1], N1, [T1|Nodes]) :- 1361 selectchk(node(Root, Ch2), N1, N2), 1362 !, 1363 merge_trees(node(Root, Ch1), node(Root, Ch2), T1), 1364 merge_nodes(T1, N2, Nodes). 1365merge_nodes([Node|T1], N1, [Node|Nodes]) :- 1366 merge_nodes(T1, N1, Nodes).
1372remove_unique_root(node(_, [node(R1, [R2])]), Tree) :- 1373 !, 1374 remove_unique_root(node(R1, [R2]), Tree). 1375remove_unique_root(Tree, Tree).
1381nav_tree(Tree, Current, Options) -->
1382 html(ul(class(nav),
1383 \object_tree(Tree, Current, Options))).
1389object_tree(node(Id, []), Target, Options) --> 1390 !, 1391 { node_class(Id, Target, Class) }, 1392 html(li(class(Class), 1393 \node(Id, Options))). 1394object_tree(node(Id, Children), Target, Options) --> 1395 !, 1396 { node_class(Id, Target, Class) }, 1397 html(li(class(Class), 1398 [ \node(Id, Options), 1399 ul(class(nav), 1400 \object_trees(Children, Target, Options)) 1401 ])). 1402object_tree(Id, Target, Options) --> 1403 !, 1404 { node_class(Id, Target, Class) }, 1405 html(li(class([obj|Class]), \node(Id, Options))). 1406 1407object_trees([], _, _) --> []. 1408object_trees([H|T], Target, Options) --> 1409 object_tree(H, Target, Options), 1410 object_trees(T, Target, Options). 1411 1412node_class(Ids, Current, Class) :- 1413 is_list(Ids), 1414 !, 1415 ( member(Id, Ids), memberchk(Id, Current) 1416 -> Class = [nav,current] 1417 ; Class = [nav] 1418 ). 1419node_class(Id, Current, Class) :- 1420 ( memberchk(Id, Current) 1421 -> Class = [nav,current] 1422 ; Class = [nav] 1423 ). 1424 1425node(file(File), Options) --> 1426 !, 1427 object_ref(file(File), [style(title)|Options]). 1428node(Id, Options) --> 1429 object_ref(Id, Options). 1430 1431 1432 /******************************* 1433 * SECTIONS * 1434 *******************************/ 1435 1436section(Type, Title) --> 1437 { string_codes(Title, Codes), 1438 wiki_codes_to_dom(Codes, [], Content0), 1439 strip_leading_par(Content0, Content), 1440 make_section(Type, Content, HTML) 1441 }, 1442 html(HTML). 1443 1444make_section(module, Title, h1(class=module, Title)). 1445make_section(section, Title, h1(class=section, Title)). 1446 1447 1448 /******************************* 1449 * PRED MODE HEADER * 1450 *******************************/
1458pred_dt(Modes, Class, Options) --> 1459 pred_dt(Modes, Class, [], _Done, Options). 1460 1461pred_dt([], _, Done, Done, _) --> 1462 []. 1463pred_dt([H|T], Class, Done0, Done, Options) --> 1464 { functor(Class, CSSClass, _) }, 1465 html(dt(class=CSSClass, 1466 [ \pred_mode(H, Done0, Done1, Options), 1467 \mode_anot(Class) 1468 ])), 1469 pred_dt(T, Class, Done1, Done, Options). 1470 1471mode_anot(privdef) --> 1472 !, 1473 html(span([class(anot), style('float:right')], 1474 '[private]')). 1475mode_anot(multidef(object(Obj))) --> 1476 !, 1477 { object_href(Obj, HREF) }, 1478 html(span([class(anot), style('float:right')], 1479 ['[', a(href(HREF), multifile), ']' 1480 ])). 1481mode_anot(multidef(file(File:_))) --> 1482 !, 1483 { file_name_on_path(File, Spec), 1484 unquote_filespec(Spec, Unquoted), 1485 doc_file_href(File, HREF) 1486 }, 1487 html(span([class(anot), style('float:right')], 1488 ['[multifile, ', a(href(HREF), '~q'-[Unquoted]), ']' 1489 ])). 1490mode_anot(multidef) --> 1491 !, 1492 html(span([class(anot), style('float:right')], 1493 '[multifile]')). 1494mode_anot(_) --> 1495 []. 1496 1497pred_mode(mode(Head,Vars), Done0, Done, Options) --> 1498 !, 1499 { bind_vars(Head, Vars) }, 1500 pred_mode(Head, Done0, Done, Options). 1501pred_mode(Head is Det, Done0, Done, Options) --> 1502 !, 1503 anchored_pred_head(Head, Done0, Done, Options), 1504 pred_det(Det). 1505pred_mode(Head, Done0, Done, Options) --> 1506 anchored_pred_head(Head, Done0, Done, Options). 1507 1508bind_vars(Term, Bindings) :- 1509 bind_vars(Bindings), 1510 anon_vars(Term). 1511 1512bind_vars([]). 1513bind_vars([Name=Var|T]) :- 1514 Var = '$VAR'(Name), 1515 bind_vars(T).
1522anon_vars(Var) :- 1523 var(Var), 1524 !, 1525 Var = '$VAR'('_'). 1526anon_vars(Term) :- 1527 compound(Term), 1528 !, 1529 Term =.. [_|Args], 1530 maplist(anon_vars, Args). 1531anon_vars(_). 1532 1533 1534anchored_pred_head(Head, Done0, Done, Options) --> 1535 { pred_anchor_name(Head, PI, Name) }, 1536 ( { memberchk(PI, Done0) } 1537 -> { Done = Done0 }, 1538 pred_head(Head) 1539 ; html([ span(style('float:right'), 1540 [ \pred_edit_or_source_button(Head, Options), 1541 &(nbsp) 1542 ]), 1543 a(name=Name, \pred_head(Head)) 1544 ]), 1545 { Done = [PI|Done0] } 1546 ). 1547 1548 Head, Options) (--> 1550 { option(edit(true), Options) }, 1551 !, 1552 pred_edit_button(Head, Options). 1553pred_edit_or_source_button(Head, Options) --> 1554 { option(source_link(true), Options) }, 1555 !, 1556 pred_source_button(Head, Options). 1557pred_edit_or_source_button(_, _) --> [].
1571pred_edit_button(_, Options) --> 1572 { \+ option(edit(true), Options) }, 1573 !. 1574pred_edit_button(PI0, Options0) --> 1575 { canonicalise_predref(PI0, PI, Options0, Options) }, 1576 pred_edit_button2(PI, Options). 1577 Name/Arity, Options) (--> 1579 { \+ ( memberchk(file(_), Options), % always edit if file and line 1580 memberchk(line(_), Options) % are given. 1581 ), 1582 functor(Head, Name, Arity), 1583 option(module(M), Options, _), 1584 \+ ( current_module(M), 1585 source_file(M:Head, _File) 1586 ) 1587 }, 1588 !. 1589pred_edit_button2(Name/Arity, Options) --> 1590 { include(edit_param, Options, Extra), 1591 http_link_to_id(pldoc_edit, 1592 [name(Name),arity(Arity)|Extra], 1593 EditHREF) 1594 }, 1595 html(a(onClick('HTTPrequest(\'' + EditHREF + '\')'), 1596 img([ class(action), 1597 alt('Edit predicate'), 1598 title('Edit predicate'), 1599 src(location_by_id(pldoc_resource)+'editpred.png') 1600 ]))). 1601pred_edit_button2(_, _) --> 1602 !, 1603 []. 1604 1605edit_param(module(_)). 1606edit_param(file(_)). 1607edit_param(line(_)).
1614object_edit_button(_, Options) --> 1615 { \+ option(edit(true), Options) }, 1616 !. 1617object_edit_button(PI, Options) --> 1618 { is_pi(PI) }, 1619 !, 1620 pred_edit_button(PI, Options). 1621object_edit_button(_, _) --> 1622 [].
1629pred_source_button(PI0, Options0) --> 1630 { canonicalise_predref(PI0, PI, Options0, Options), 1631 option(module(M), Options, _), 1632 pred_source_href(PI, M, HREF), ! 1633 }, 1634 html(a([ href(HREF) 1635 ], 1636 img([ class(action), 1637 alt('Source'), 1638 title('Show source'), 1639 src(location_by_id(pldoc_resource)+'source.png') 1640 ]))). 1641pred_source_button(_, _) --> 1642 [].
1649object_source_button(PI, Options) --> 1650 { is_pi(PI), 1651 option(source_link(true), Options, true) 1652 }, 1653 !, 1654 pred_source_button(PI, Options). 1655object_source_button(_, _) --> 1656 [].
module(M)
to Options.1664canonicalise_predref(M:PI0, PI, Options0, [module(M)|Options]) :- 1665 !, 1666 canonicalise_predref(PI0, PI, Options0, Options). 1667canonicalise_predref(//(Head), PI, Options0, Options) :- 1668 !, 1669 functor(Head, Name, Arity), 1670 PredArity is Arity + 2, 1671 canonicalise_predref(Name/PredArity, PI, Options0, Options). 1672canonicalise_predref(Name//Arity, PI, Options0, Options) :- 1673 integer(Arity), Arity >= 0, 1674 !, 1675 PredArity is Arity + 2, 1676 canonicalise_predref(Name/PredArity, PI, Options0, Options). 1677canonicalise_predref(PI, PI, Options, Options) :- 1678 PI = Name/Arity, 1679 atom(Name), integer(Arity), Arity >= 0, 1680 !. 1681canonicalise_predref(Head, PI, Options0, Options) :- 1682 functor(Head, Name, Arity), 1683 canonicalise_predref(Name/Arity, PI, Options0, Options).
span
using
class pred
and the arguments and var
using class arglist
.1691pred_head(Var) --> 1692 { var(Var), 1693 !, 1694 instantiation_error(Var) 1695 }. 1696pred_head(//(Head)) --> 1697 !, 1698 pred_head(Head), 1699 html(//). 1700pred_head(M:Head) --> 1701 html([span(class=module, M), :]), 1702 pred_head(Head). 1703pred_head(Head) --> 1704 { atom(Head) }, 1705 !, 1706 html(b(class=pred, Head)). 1707pred_head(Head) --> % Infix operators 1708 { Head =.. [Functor,Left,Right], 1709 is_op_type(Functor, infix) 1710 }, 1711 !, 1712 html([ var(class=arglist, \pred_arg(Left, 1)), 1713 ' ', b(class=pred, Functor), ' ', 1714 var(class=arglist, \pred_arg(Right, 2)) 1715 ]). 1716pred_head(Head) --> % Prefix operators 1717 { Head =.. [Functor,Arg], 1718 is_op_type(Functor, prefix) 1719 }, 1720 !, 1721 html([ b(class=pred, Functor), ' ', 1722 var(class=arglist, \pred_arg(Arg, 1)) 1723 ]). 1724pred_head(Head) --> % Postfix operators 1725 { Head =.. [Functor,Arg], 1726 is_op_type(Functor, postfix) 1727 }, 1728 !, 1729 html([ var(class=arglist, \pred_arg(Arg, 1)), 1730 ' ', b(class=pred, Functor) 1731 ]). 1732pred_head({Head}) --> 1733 !, 1734 html([ b(class=pred, '{'), 1735 var(class=arglist, 1736 \pred_args([Head], 1)), 1737 b(class=pred, '}') 1738 ]). 1739pred_head(Head) --> % Plain terms 1740 { Head =.. [Functor|Args] }, 1741 html([ b(class=pred, Functor), 1742 var(class=arglist, 1743 [ '(', \pred_args(Args, 1), ')' ]) 1744 ]).
prefix
,
infix
or postfix
.1751is_op_type(Functor, Type) :- 1752 current_op(_Pri, F, Functor), 1753 op_type(F, Type). 1754 1755op_type(fx, prefix). 1756op_type(fy, prefix). 1757op_type(xf, postfix). 1758op_type(yf, postfix). 1759op_type(xfx, infix). 1760op_type(xfy, infix). 1761op_type(yfx, infix). 1762op_type(yfy, infix). 1763 1764 1765pred_args([], _) --> 1766 []. 1767pred_args([H|T], I) --> 1768 pred_arg(H, I), 1769 ( {T==[]} 1770 -> [] 1771 ; html(', '), 1772 { I2 is I + 1 }, 1773 pred_args(T, I2) 1774 ). 1775 1776pred_arg(Var, I) --> 1777 { var(Var) }, 1778 !, 1779 html(['Arg', I]). 1780pred_arg(...(Term), I) --> 1781 !, 1782 pred_arg(Term, I), 1783 html('...'). 1784pred_arg(Term, I) --> 1785 { Term =.. [Ind,Arg], 1786 mode_indicator(Ind) 1787 }, 1788 !, 1789 html([Ind, \pred_arg(Arg, I)]). 1790pred_arg(Arg:Type, _) --> 1791 !, 1792 html([\argname(Arg), :, \argtype(Type)]). 1793pred_arg(Arg, _) --> 1794 argname(Arg). 1795 1796argname('$VAR'(Name)) --> 1797 !, 1798 html(Name). 1799argname(Name) --> 1800 !, 1801 html(Name). 1802 1803argtype(Term) --> 1804 { format(string(S), '~W', 1805 [ Term, 1806 [ quoted(true), 1807 numbervars(true) 1808 ] 1809 ]) }, 1810 html(S). 1811 1812pred_det(unknown) --> 1813 []. 1814pred_det(Det) --> 1815 html([' is ', b(class=det, Det)]).
doc_wiki.pl
.
1824term(_, Atom, []) --> 1825 { atomic(Atom), 1826 !, 1827 format(string(S), '~W', [Atom,[quoted(true)]]) 1828 }, 1829 html(span(class=functor, S)). 1830term(_, Key:Type, [TypeName=Type]) --> 1831 { atomic(Key) 1832 }, 1833 !, 1834 html([span(class='pl-key', Key), :, span(class('pl-var'), TypeName)]). 1835term(_, Term, Bindings) --> 1836 { is_mode(Term is det), % HACK. Bit too strict? 1837 bind_vars(Bindings) 1838 }, 1839 !, 1840 pred_head(Term). 1841term(_, Term, Bindings) --> 1842 term(Term, 1843 [ variable_names(Bindings), 1844 quoued(true) 1845 ]). 1846 1847 1848 /******************************* 1849 * PREDREF * 1850 *******************************/
Current file must be available through the global variable
pldoc_file
. If this variable not set it creates a link to
/doc/<file>#anchor. Such links only work in the online browser.
1863predref(Term) --> 1864 { catch(nb_getval(pldoc_options, Options), _, Options = []) }, 1865 predref(Term, Options). 1866 1867predref(Obj, Options) --> 1868 { Obj = _:_, 1869 doc_comment(Obj, File:_Line, _, _), 1870 ( ( option(files(Map), Options) 1871 -> memberchk(file(File,_), Map) 1872 ; true 1873 ) 1874 -> object_href(Obj, HREF, Options) 1875 ; manref(Obj, HREF, Options) 1876 ) 1877 }, 1878 !, 1879 html(a(href(HREF), \object_name(Obj, [qualify(true)|Options]))). 1880predref(M:Term, Options) --> 1881 !, 1882 predref(Term, M, Options). 1883predref(Term, Options) --> 1884 predref(Term, _, Options). 1885 1886predref(Name/Arity, _, Options) --> % Builtin; cannot be overruled 1887 { prolog:doc_object_summary(Name/Arity, manual, _, _), 1888 !, 1889 manref(Name/Arity, HREF, Options) 1890 }, 1891 html(a([class=builtin, href=HREF], [Name, /, Arity])). 1892predref(Name/Arity, _, Options) --> % From packages 1893 { option(prefer(manual), Options), 1894 prolog:doc_object_summary(Name/Arity, Category, _, _), 1895 !, 1896 manref(Name/Arity, HREF, Options) 1897 }, 1898 html(a([class=Category, href=HREF], [Name, /, Arity])). 1899predref(Obj, Module, Options) --> % Local 1900 { doc_comment(Module:Obj, File:_Line, _, _), 1901 ( option(files(Map), Options) 1902 -> memberchk(file(File,_), Map) 1903 ; true 1904 ) 1905 }, 1906 !, 1907 object_ref(Module:Obj, Options). 1908predref(Name/Arity, Module, Options) --> 1909 { \+ option(files(_), Options), 1910 pred_href(Name/Arity, Module, HREF) 1911 }, 1912 !, 1913 html(a(href=HREF, [Name, /, Arity])). 1914predref(Name//Arity, Module, Options) --> 1915 { \+ option(files(_), Options), 1916 PredArity is Arity + 2, 1917 pred_href(Name/PredArity, Module, HREF) 1918 }, 1919 !, 1920 html(a(href=HREF, [Name, //, Arity])). 1921predref(PI, _, Options) --> % From packages 1922 { canonical_pi(PI, CPI, HTML), 1923 ( option(files(_), Options) 1924 -> Category = extmanual 1925 ; prolog:doc_object_summary(CPI, Category, _, _) 1926 ), 1927 manref(CPI, HREF, Options) 1928 }, 1929 html(a([class=Category, href=HREF], HTML)). 1930predref(PI, _, _Options) --> 1931 { canonical_pi(PI, _CPI, HTML) 1932 }, 1933 !, 1934 html(span(class=undef, HTML)). 1935predref(Callable, Module, Options) --> 1936 { callable(Callable), 1937 functor(Callable, Name, Arity) 1938 }, 1939 predref(Name/Arity, Module, Options). 1940 1941canonical_pi(Name/Arity, Name/Arity, [Name, /, Arity]) :- 1942 atom(Name), integer(Arity), 1943 !. 1944canonical_pi(Name//Arity, Name/Arity2, [Name, //, Arity]) :- 1945 atom(Name), integer(Arity), 1946 !, 1947 Arity2 is Arity+2.
name/arity
, non-linking predicate indicator.
1953nopredref(PI) -->
1954 { canonical_pi(PI, _CPI, HTML)
1955 },
1956 !,
1957 html(span(class=nopredref, HTML)).
1965flagref(Flag) -->
1966 html(code(Flag)).
1973cite(Citations) --> 1974 html('['), citations(Citations), html(']'). 1975 1976citations([]) --> []. 1977citations([H|T]) --> 1978 citation(H), 1979 ( {T==[]} 1980 -> [] 1981 ; [';'], 1982 citations(T) 1983 ). 1984 1985citation(H) --> 1986 html([@,H]).
man_server(+Server)
.1994manref(PI, HREF, Options) :- 1995 predname(PI, PredName), 1996 ( option(files(_Map), Options) 1997 -> option(man_server(Server), Options, 1998 'http://www.swi-prolog.org/pldoc'), 1999 uri_components(Server, Comp0), 2000 uri_data(path, Comp0, Path0), 2001 directory_file_path(Path0, man, Path), 2002 uri_data(path, Comp0, Path, Components), 2003 uri_query_components(Query, [predicate=PredName]), 2004 uri_data(search, Components, Query), 2005 uri_components(HREF, Components) 2006 ; http_link_to_id(pldoc_man, [predicate=PredName], HREF) 2007 ). 2008 2009predname(Name/Arity, PredName) :- 2010 !, 2011 format(atom(PredName), '~w/~d', [Name, Arity]). 2012predname(Module:Name/Arity, PredName) :- 2013 !, 2014 format(atom(PredName), '~w:~w/~d', [Module, Name, Arity]).
2028pred_href(Name/Arity, Module, HREF) :- 2029 format(string(FragmentId), '~w/~d', [Name, Arity]), 2030 uri_data(fragment, Components, FragmentId), 2031 functor(Head, Name, Arity), 2032 ( catch(relative_file(Module:Head, File), _, fail) 2033 -> uri_data(path, Components, File), 2034 uri_components(HREF, Components) 2035 ; in_file(Module:Head, File) 2036 -> ( current_prolog_flag(home, SWI), 2037 sub_atom(File, 0, _, _, SWI), 2038 prolog:doc_object_summary(Name/Arity, packages, _, _) 2039 -> http_link_to_id(pldoc_man, [predicate=FragmentId], HREF) 2040 ; http_location_by_id(pldoc_doc, DocHandler), 2041 atom_concat(DocHandler, File, Path), 2042 uri_data(path, Components, Path), 2043 uri_components(HREF, Components) 2044 ) 2045 ). 2046 2047relative_file(Head, '') :- 2048 b_getval(pldoc_file, CurrentFile), CurrentFile \== [], 2049 in_file(Head, CurrentFile), 2050 !. 2051relative_file(Head, RelFile) :- 2052 b_getval(pldoc_file, CurrentFile), CurrentFile \== [], 2053 in_file(Head, DefFile), 2054 relative_file_name(DefFile, CurrentFile, RelFile).
2060pred_source_href(Name/Arity, Module, HREF) :-
2061 format(string(FragmentId), '~w/~d', [Name, Arity]),
2062 uri_data(fragment, Components, FragmentId),
2063 uri_query_components(Query, [show=src]),
2064 uri_data(search, Components, Query),
2065 functor(Head, Name, Arity),
2066 ( catch(relative_file(Module:Head, File), _, fail)
2067 -> uri_data(path, Components, File),
2068 uri_components(HREF, Components)
2069 ; in_file(Module:Head, File0)
2070 -> insert_alias(File0, File),
2071 http_location_by_id(pldoc_doc, DocHandler),
2072 atom_concat(DocHandler, File, Path),
2073 uri_data(path, Components, Path),
2074 uri_components(HREF, Components)
2075 ).
2084object_ref([], _) --> 2085 !, 2086 []. 2087object_ref([H|T], Options) --> 2088 !, 2089 object_ref(H, Options), 2090 ( {T == []} 2091 -> html(', '), 2092 object_ref(T, Options) 2093 ; [] 2094 ). 2095object_ref(Obj, Options) --> 2096 { object_href(Obj, HREF, Options) 2097 }, 2098 html(a(href(HREF), \object_name(Obj, Options))).
2105object_href(Obj, HREF) :- 2106 object_href(Obj, HREF, []). 2107 2108object_href(M:PI0, HREF, Options) :- 2109 option(files(Map), Options), 2110 ( module_property(M, file(File)) 2111 -> true 2112 ; xref_module(File, M) 2113 ), 2114 memberchk(file(File, DocFile), Map), 2115 !, 2116 file_base_name(DocFile, LocalFile), % TBD: proper directory index 2117 expand_pi(PI0, PI), 2118 term_to_string(PI, PIS), 2119 uri_data(path, Components, LocalFile), 2120 uri_data(fragment, Components, PIS), 2121 uri_components(HREF, Components). 2122object_href(file(File), HREF, _Options) :- 2123 doc_file_href(File, HREF), 2124 !. 2125object_href(directory(Dir), HREF, _Options) :- 2126 directory_file_path(Dir, 'index.html', Index), 2127 doc_file_href(Index, HREF), 2128 !. 2129object_href(Obj, HREF, _Options) :- 2130 prolog:doc_object_href(Obj, HREF), 2131 !. 2132object_href(Obj0, HREF, _Options) :- 2133 localise_object(Obj0, Obj), 2134 term_to_string(Obj, String), 2135 http_link_to_id(pldoc_object, [object=String], HREF). 2136 2137expand_pi(Name//Arity0, Name/Arity) :- 2138 !, 2139 Arity is Arity0+2. 2140expand_pi(PI, PI).
2148localise_object(Obj0, Obj) :- 2149 prolog:doc_canonical_object(Obj0, Obj), 2150 !. 2151localise_object(Obj, Obj).
2159term_to_string(Term, String) :-
2160 State = state(-),
2161 ( numbervars(Term, 0, _, [singletons(true)]),
2162 with_output_to(string(String),
2163 write_term(Term,
2164 [ numbervars(true),
2165 quoted(true)
2166 ])),
2167 nb_setarg(1, State, String),
2168 fail
2169 ; arg(1, State, String)
2170 ).
inline
or title
number
, title
or number_title
2184object_name(Obj, Options) --> 2185 { option(style(Style), Options, inline) 2186 }, 2187 object_name(Style, Obj, Options). 2188 2189object_name(title, Obj, Options) --> 2190 { merge_options(Options, [secref_style(title)], Options1) }, 2191 prolog:doc_object_link(Obj, Options1), 2192 !. 2193object_name(inline, Obj, Options) --> 2194 prolog:doc_object_link(Obj, Options), 2195 !. 2196object_name(title, f(Name/Arity), _Options) --> 2197 !, 2198 html(['Function ', Name, /, Arity]). 2199object_name(inline, f(Name/Arity), _Options) --> 2200 !, 2201 html([Name, /, Arity]). 2202object_name(Style, PI, Options) --> 2203 { is_pi(PI) }, 2204 !, 2205 pi(Style, PI, Options). 2206object_name(inline, Module:module(_Title), _) --> 2207 !, 2208 { module_property(Module, file(File)), 2209 file_base_name(File, Base) 2210 }, 2211 !, 2212 html(Base). 2213object_name(title, Module:module(Title), _) --> 2214 { module_property(Module, file(File)), 2215 file_base_name(File, Base) 2216 }, 2217 !, 2218 html([Base, ' -- ', Title]). 2219object_name(title, file(File), _) --> 2220 { module_property(Module, file(File)), 2221 doc_comment(Module:module(Title), _, _, _), 2222 !, 2223 file_base_name(File, Base) 2224 }, 2225 html([Base, ' -- ', Title]). 2226object_name(_, file(File), _) --> 2227 { file_base_name(File, Base) }, 2228 html(Base). 2229object_name(_, directory(Dir), _) --> 2230 { file_base_name(Dir, Base) }, 2231 html(Base). 2232object_name(_, module(Title), _Options) --> 2233 { print_message(warning, 2234 pldoc(module_comment_outside_module(Title))) 2235 }. 2236 2237pi(title, PI, Options) --> 2238 pi_type(PI), 2239 pi(PI, Options). 2240pi(inline, PI, Options) --> 2241 pi(PI, Options). 2242 2243pi(M:PI, Options) --> 2244 !, 2245 ( { option(qualify(true), Options) } 2246 -> html([span(class(module), M), :]) 2247 ; [] 2248 ), 2249 pi(PI, Options). 2250pi(Name/Arity, _) --> 2251 !, 2252 html([Name, /, Arity]). 2253pi(Name//Arity, _) --> 2254 html([Name, //, Arity]). 2255 2256pi_type(_:PI) --> 2257 !, 2258 pi_type(PI). 2259pi_type(_/_) --> 2260 html(['Predicate ']). 2261pi_type(_//_) --> 2262 html(['Grammar rule ']).
2274in_file(Module:Head, File) :- 2275 !, 2276 distinct(File, in_file(Module, Head, File)). 2277in_file(Head, File) :- 2278 distinct(File, in_file(_, Head, File)). 2279 2280in_file(Module, Head, File) :- 2281 var(Module), 2282 ( predicate_property(system:Head, foreign) 2283 -> !, 2284 fail 2285 ; predicate_property(system:Head, file(File)), 2286 \+ system_arithmetic_function(Head) 2287 -> ! 2288 ; predicate_property(Head, autoload(File0)) 2289 -> !, 2290 file_name_extension(File0, pl, File) 2291 ; exported_from(Module, Head, File), 2292 module_property(Module, class(library)) 2293 ). 2294in_file(Module, Head, File) :- 2295 nonvar(Module), 2296 predicate_property(Module:Head, file(File)), 2297 \+ predicate_property(Module:Head, imported_from(_)). 2298in_file(Module, Head, File) :- 2299 xref_defined(File, Head, How), 2300 xref_current_source(File), 2301 atom(File), % only plain files 2302 xref_module(File, Module), 2303 How \= imported(_From). 2304in_file(Module, Head, File) :- 2305 exported_from(Module, Head, File). 2306in_file(Module, Head, File) :- 2307 predicate_property(Module:Head, file(File)), 2308 \+ predicate_property(Module:Head, imported_from(_)). 2309in_file(Module, Head, File) :- 2310 current_module(Module), 2311 source_file(Module:Head, File). 2312 2313exported_from(Module, Head, File) :- 2314 distinct(Primary, 2315 ( predicate_property(Module:Head, exported), 2316 ( predicate_property(Module:Head, imported_from(Primary)) 2317 -> true 2318 ; Primary = Module 2319 ))), 2320 module_property(Primary, file(File)). 2321 2322:- multifile 2323 arithmetic:evaluable/2. 2324 2325system_arithmetic_function(Head) :- 2326 functor(Head, Name, Arity), 2327 FArith is Arity-1, 2328 FArith >= 0, 2329 functor(FHead, Name, FArith), 2330 arithmetic:evaluable(FHead, system).
file(File)
terms in the DOM term generated by wiki.pl. Supported
options are:
file(Name, Link)
that specifies that we must
user Link for the given physical file Name.2361file(File) --> 2362 file(File, []). 2363 2364file(File, Options) --> 2365 { catch(nb_getval(pldoc_options, GenOptions), _, GenOptions = []), 2366 merge_options(Options, GenOptions, FinalOptions) 2367 }, 2368 link_file(File, FinalOptions), 2369 !. 2370file(File, Options) --> 2371 { option(edit_handler(Handler), Options), 2372 http_current_request(Request), 2373 memberchk(path(Path), Request), 2374 absolute_file_name(File, Location, 2375 [ relative_to(Path) 2376 ]), 2377 http_link_to_id(Handler, [location(Location)], HREF), 2378 format(atom(Title), 'Click to create ~w', [File]) 2379 }, 2380 html(a([href(HREF), class(nofile), title(Title)], File)). 2381file(File, _) --> 2382 html(code(class(nofile), File)). 2383 2384link_file(File, Options) --> 2385 { file_href(File, HREF, Options), 2386 option(label(Label), Options, File), 2387 option(class(Class), Options, file) 2388 }, 2389 html(a([class(Class), href(HREF)], Label)).
2395file_href(_, HREF, Options) :- 2396 option(href(HREF), Options), 2397 !. 2398file_href(File, HREF, Options) :- 2399 file_href_real(File, HREF0, Options), 2400 map_extension(HREF0, HREF, Options).
map_extension(+Pairs)
2408map_extension(HREF0, HREF, Options) :- 2409 option(map_extension(Map), Options), 2410 file_name_extension(Base, Old, HREF0), 2411 memberchk(Old-New, Map), 2412 !, 2413 file_name_extension(Base, New, HREF). 2414map_extension(HREF, HREF, _). 2415 2416 2417file_href_real(File, HREF, Options) :- 2418 ( option(absolute_path(Path), Options) 2419 ; existing_linked_file(File, Path) 2420 ), 2421 !, 2422 ( option(files(Map), Options), 2423 memberchk(file(Path, LinkFile), Map) 2424 -> true 2425 ; LinkFile = Path 2426 ), 2427 file_href(LinkFile, HREF). 2428file_href_real(File, HREF, _) :- 2429 directory_alias(Alias), 2430 Term =.. [Alias,File], 2431 absolute_file_name(Term, _, 2432 [ access(read), 2433 file_errors(fail) 2434 ]), 2435 !, 2436 http_absolute_location(Term, HREF, []). 2437 2438directory_alias(icons). 2439directory_alias(css).
pldoc_file
.2449file_href(Path, HREF) :- % a loaded Prolog file 2450 source_file(Path), 2451 !, 2452 doc_file_href(Path, HREF). 2453file_href(Path, HREF) :- 2454 ( nb_current(pldoc_output, CFile) 2455 ; nb_current(pldoc_file, CFile) 2456 ), 2457 CFile \== [], 2458 !, 2459 relative_file_name(Path, CFile, HREF). 2460file_href(Path, Path).
2468existing_linked_file(File, Path) :-
2469 catch(b_getval(pldoc_file, CurrentFile), _, fail),
2470 CurrentFile \== [],
2471 absolute_file_name(File, Path,
2472 [ relative_to(CurrentFile),
2473 access(read),
2474 file_errors(fail)
2475 ]).
include(File,
Type)
terms in the DOM term generated by wiki.pl if it
encounters [[file.ext]].2485include(PI, predicate, _) --> 2486 !, 2487 ( html_tokens_for_predicates(PI, []) 2488 -> [] 2489 ; html(['[[', \predref(PI), ']]']) 2490 ). 2491include(File, image, Options) --> 2492 { file_name_extension(_, svg, File), 2493 file_href(File, HREF, Options), 2494 !, 2495 include(image_attribute, Options, Attrs0), 2496 merge_options(Attrs0, 2497 [ alt(File), 2498 data(HREF), 2499 type('image/svg+xml') 2500 ], Attrs) 2501 }, 2502 ( { option(caption(Caption), Options) } 2503 -> html(div(class(figure), 2504 [ div(class(image), object(Attrs, [])), 2505 div(class(caption), Caption) 2506 ])) 2507 ; html(object(Attrs, [])) 2508 ). 2509include(File, image, Options) --> 2510 { file_href(File, HREF, Options), 2511 !, 2512 include(image_attribute, Options, Attrs0), 2513 merge_options(Attrs0, 2514 [ alt(File), 2515 border(0), 2516 src(HREF) 2517 ], Attrs) 2518 }, 2519 ( { option(caption(Caption), Options) } 2520 -> html(div(class(figure), 2521 [ div(class(image), img(Attrs)), 2522 div(class(caption), Caption) 2523 ])) 2524 ; html(img(Attrs)) 2525 ). 2526include(File, wiki, _Options) --> % [[file.txt]] is included 2527 { access_file(File, read), 2528 !, 2529 read_file_to_codes(File, String, []), 2530 wiki_codes_to_dom(String, [], DOM) 2531 }, 2532 html(DOM). 2533include(File, _Type, Options) --> 2534 link_file(File, Options), 2535 !. 2536include(File, _, _) --> 2537 html(code(class(nofile), ['[[',File,']]'])). 2538 2539image_attribute(src(_)). 2540image_attribute(alt(_)). 2541image_attribute(title(_)). 2542image_attribute(align(_)). 2543image_attribute(width(_)). 2544image_attribute(height(_)). 2545image_attribute(border(_)). 2546image_attribute(class(_)). 2547image_attribute(style(_)).
* [[member/2]] * [[append/3]]
2560html_tokens_for_predicates([], _Options) --> 2561 []. 2562html_tokens_for_predicates([H|T], Options) --> 2563 !, 2564 html_tokens_for_predicates(H, Options), 2565 html_tokens_for_predicates(T, Options). 2566html_tokens_for_predicates(PI, Options) --> 2567 { PI = _:_/_, 2568 !, 2569 ( doc_comment(PI, Pos, _Summary, Comment) 2570 -> true 2571 ; Comment = '' 2572 ) 2573 }, 2574 object(PI, [Pos-Comment], [dl], _, Options). 2575html_tokens_for_predicates(Spec, Options) --> 2576 { findall(PI, documented_pi(Spec, PI), List), 2577 List \== [], ! 2578 }, 2579 html_tokens_for_predicates(List, Options). 2580html_tokens_for_predicates(Spec, Options) --> 2581 man_page(Spec, 2582 [ links(false), % no header 2583 navtree(false), % no navigation tree 2584 footer(false), % no footer 2585 synopsis(false) % no synopsis 2586 | Options 2587 ]). 2588 2589 2590documented_pi(Spec, PI) :- 2591 generalise_spec(Spec, PI), 2592 doc_comment(PI, _Pos, _Summary, _Comment). 2593 2594generalise_spec(Name/Arity, _M:Name/Arity). 2595generalise_spec(Name//Arity, _M:Name//Arity). 2596 2597 2598 /******************************* 2599 * WIKI FILES * 2600 *******************************/
2607doc_for_wiki_file(FileSpec, Options) :- 2608 absolute_file_name(FileSpec, File, 2609 [ access(read) 2610 ]), 2611 read_file_to_codes(File, String, []), 2612 b_setval(pldoc_file, File), 2613 call_cleanup(reply_wiki_page(File, String, Options), 2614 nb_delete(pldoc_file)). 2615 2616reply_wiki_page(File, String, Options) :- 2617 wiki_codes_to_dom(String, [], DOM0), 2618 title(DOM0, File, Title), 2619 insert_edit_button(DOM0, File, DOM, Options), 2620 reply_html_page(pldoc(wiki), 2621 title(Title), 2622 [ \html_requires(pldoc) 2623 | DOM 2624 ]). 2625 2626title(DOM, _, Title) :- 2627 sub_term(h1(_,Title), DOM), 2628 !. 2629title(_, File, Title) :- 2630 file_base_name(File, Title). 2631 DOM, _, DOM, Options) (:- 2633 option(edit(false), Options, false), 2634 !. 2635insert_edit_button([h1(Attrs,Title)|DOM], File, 2636 [h1(Attrs,[ span(style('float:right'), 2637 \edit_button(File, [edit(true)])) 2638 | Title 2639 ])|DOM], _) :- !. 2640insert_edit_button(DOM, File, 2641 [ h1(class(wiki), 2642 [ span(style('float:right'), 2643 \edit_button(File, [edit(true)])) 2644 ]) 2645 | DOM 2646 ], _). 2647 2648 2649 /******************************* 2650 * ANCHORS * 2651 *******************************/
2657mode_anchor_name(Var, _) :- 2658 var(Var), 2659 !, 2660 instantiation_error(Var). 2661mode_anchor_name(mode(Head, _), Anchor) :- 2662 !, 2663 mode_anchor_name(Head, Anchor). 2664mode_anchor_name(Head is _Det, Anchor) :- 2665 !, 2666 mode_anchor_name(Head, Anchor). 2667mode_anchor_name(Head, Anchor) :- 2668 pred_anchor_name(Head, _, Anchor).
2675pred_anchor_name(//(Head), Name/Arity, Anchor) :- 2676 !, 2677 functor(Head, Name, DCGArity), 2678 Arity is DCGArity+2, 2679 format(atom(Anchor), '~w/~d', [Name, Arity]). 2680pred_anchor_name(Head, Name/Arity, Anchor) :- 2681 functor(Head, Name, Arity), 2682 format(atom(Anchor), '~w/~d', [Name, Arity]). 2683 2684:- multifile prolog:message//1. 2685 2686prologmessage(pldoc(module_comment_outside_module(Title))) --> 2687 [ 'PlDoc comment <module> ~w does not appear in a module'-[Title] ]
PlDoc HTML backend
This module translates the Herbrand term from the documentation extracting module
doc_wiki.pl
into HTML+CSS.