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-2022, 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').
args(List) created by doc_wiki.pl. Params is a
list of arg(Name, Descr).1282args(Params) --> 1283 html([ dt(class=tag, 'Arguments:'), 1284 dd(table(class=arglist, 1285 \arg_list(Params))) 1286 ]). 1287 1288arg_list([]) --> 1289 []. 1290arg_list([H|T]) --> 1291 argument(H), 1292 arg_list(T). 1293 1294argument(arg(Name,Descr)) --> 1295 html(tr([td(var(Name)), td(class=argdescr, ['- '|Descr])])). 1296 1297 1298 /******************************* 1299 * NAVIGATION TREE * 1300 *******************************/
node(Object, Children).1307objects_nav_tree(Objects, Tree) :- 1308 maplist(object_nav_tree, Objects, Trees), 1309 union_trees(Trees, Tree0), 1310 remove_unique_root(Tree0, Tree). 1311 (Obj, Tree) :- 1313 Node = node(directory(Dir), FileNodes), 1314 FileNode = node(file(File), Siblings), 1315 doc_comment(Obj, File:_Line, _Summary, _Comment), 1316 !, 1317 file_directory_name(File, Dir), 1318 sibling_file_nodes(Dir, FileNodes0), 1319 selectchk(node(file(File),[]), FileNodes0, FileNode, FileNodes), 1320 findall(Sibling, doc_comment(Sibling, File:_, _, _), Siblings0), 1321 delete(Siblings0, _:module(_), Siblings1), 1322 doc_hide_private(Siblings1, Siblings2, []), 1323 flatten(Siblings2, Siblings), % a comment may describe objects 1324 embed_directories(Node, Tree). 1325 1326sibling_file_nodes(Dir, Nodes) :- 1327 findall(node(file(File), []), 1328 ( source_file(File), 1329 file_directory_name(File, Dir) 1330 ), 1331 Nodes). 1332 1333embed_directories(Node, Tree) :- 1334 Node = node(file(File), _), 1335 !, 1336 file_directory_name(File, Dir), 1337 Super = node(directory(Dir), [Node]), 1338 embed_directories(Super, Tree). 1339embed_directories(Node, Tree) :- 1340 Node = node(directory(Dir), _), 1341 file_directory_name(Dir, SuperDir), 1342 SuperDir \== Dir, 1343 !, 1344 Super = node(directory(SuperDir), [Node]), 1345 embed_directories(Super, Tree). 1346embed_directories(Tree, Tree). 1347 1348 1349union_trees([Tree], Tree) :- !. 1350union_trees([T1,T2|Trees], Tree) :- 1351 merge_trees(T1, T2, M1), 1352 union_trees([M1|Trees], Tree). 1353 1354merge_trees(node(R, Ch1), node(R, Ch2), node(R, Ch)) :- 1355 merge_nodes(Ch1, Ch2, Ch). 1356 1357merge_nodes([], Ch, Ch) :- !. 1358merge_nodes(Ch, [], Ch) :- !. 1359merge_nodes([node(Root, Ch1)|T1], N1, [T1|Nodes]) :- 1360 selectchk(node(Root, Ch2), N1, N2), 1361 !, 1362 merge_trees(node(Root, Ch1), node(Root, Ch2), T1), 1363 merge_nodes(T1, N2, Nodes). 1364merge_nodes([Node|T1], N1, [Node|Nodes]) :- 1365 merge_nodes(T1, N1, Nodes).
1371remove_unique_root(node(_, [node(R1, [R2])]), Tree) :- 1372 !, 1373 remove_unique_root(node(R1, [R2]), Tree). 1374remove_unique_root(Tree, Tree).
1380nav_tree(Tree, Current, Options) -->
1381 html(ul(class(nav),
1382 \object_tree(Tree, Current, Options))).1388object_tree(node(Id, []), Target, Options) --> 1389 !, 1390 { node_class(Id, Target, Class) }, 1391 html(li(class(Class), 1392 \node(Id, Options))). 1393object_tree(node(Id, Children), Target, Options) --> 1394 !, 1395 { node_class(Id, Target, Class) }, 1396 html(li(class(Class), 1397 [ \node(Id, Options), 1398 ul(class(nav), 1399 \object_trees(Children, Target, Options)) 1400 ])). 1401object_tree(Id, Target, Options) --> 1402 !, 1403 { node_class(Id, Target, Class) }, 1404 html(li(class([obj|Class]), \node(Id, Options))). 1405 1406object_trees([], _, _) --> []. 1407object_trees([H|T], Target, Options) --> 1408 object_tree(H, Target, Options), 1409 object_trees(T, Target, Options). 1410 1411node_class(Ids, Current, Class) :- 1412 is_list(Ids), 1413 !, 1414 ( member(Id, Ids), memberchk(Id, Current) 1415 -> Class = [nav,current] 1416 ; Class = [nav] 1417 ). 1418node_class(Id, Current, Class) :- 1419 ( memberchk(Id, Current) 1420 -> Class = [nav,current] 1421 ; Class = [nav] 1422 ). 1423 1424node(file(File), Options) --> 1425 !, 1426 object_ref(file(File), [style(title)|Options]). 1427node(Id, Options) --> 1428 object_ref(Id, Options). 1429 1430 1431 /******************************* 1432 * SECTIONS * 1433 *******************************/ 1434 1435section(Type, Title) --> 1436 { string_codes(Title, Codes), 1437 wiki_codes_to_dom(Codes, [], Content0), 1438 strip_leading_par(Content0, Content), 1439 make_section(Type, Content, HTML) 1440 }, 1441 html(HTML). 1442 1443make_section(module, Title, h1(class=module, Title)). 1444make_section(section, Title, h1(class=section, Title)). 1445 1446 1447 /******************************* 1448 * PRED MODE HEADER * 1449 *******************************/
1457pred_dt(Modes, Class, Options) --> 1458 pred_dt(Modes, Class, [], _Done, Options). 1459 1460pred_dt([], _, Done, Done, _) --> 1461 []. 1462pred_dt([H|T], Class, Done0, Done, Options) --> 1463 { functor(Class, CSSClass, _) }, 1464 html(dt(class=CSSClass, 1465 [ \pred_mode(H, Done0, Done1, Options), 1466 \mode_anot(Class) 1467 ])), 1468 pred_dt(T, Class, Done1, Done, Options). 1469 1470mode_anot(privdef) --> 1471 !, 1472 html(span([class(anot), style('float:right')], 1473 '[private]')). 1474mode_anot(multidef(object(Obj))) --> 1475 !, 1476 { object_href(Obj, HREF) }, 1477 html(span([class(anot), style('float:right')], 1478 ['[', a(href(HREF), multifile), ']' 1479 ])). 1480mode_anot(multidef(file(File:_))) --> 1481 !, 1482 { file_name_on_path(File, Spec), 1483 unquote_filespec(Spec, Unquoted), 1484 doc_file_href(File, HREF) 1485 }, 1486 html(span([class(anot), style('float:right')], 1487 ['[multifile, ', a(href(HREF), '~q'-[Unquoted]), ']' 1488 ])). 1489mode_anot(multidef) --> 1490 !, 1491 html(span([class(anot), style('float:right')], 1492 '[multifile]')). 1493mode_anot(_) --> 1494 []. 1495 1496pred_mode(mode(Head,Vars), Done0, Done, Options) --> 1497 !, 1498 { bind_vars(Head, Vars) }, 1499 pred_mode(Head, Done0, Done, Options). 1500pred_mode(Head is Det, Done0, Done, Options) --> 1501 !, 1502 anchored_pred_head(Head, Done0, Done, Options), 1503 pred_det(Det). 1504pred_mode(Head, Done0, Done, Options) --> 1505 anchored_pred_head(Head, Done0, Done, Options). 1506 1507bind_vars(Term, Bindings) :- 1508 bind_vars(Bindings), 1509 anon_vars(Term). 1510 1511bind_vars([]). 1512bind_vars([Name=Var|T]) :- 1513 Var = '$VAR'(Name), 1514 bind_vars(T).
1521anon_vars(Var) :- 1522 var(Var), 1523 !, 1524 Var = '$VAR'('_'). 1525anon_vars(Term) :- 1526 compound(Term), 1527 !, 1528 Term =.. [_|Args], 1529 maplist(anon_vars, Args). 1530anon_vars(_). 1531 1532 1533anchored_pred_head(Head, Done0, Done, Options) --> 1534 { pred_anchor_name(Head, PI, Name) }, 1535 ( { memberchk(PI, Done0) } 1536 -> { Done = Done0 }, 1537 pred_head(Head) 1538 ; html([ span(style('float:right'), 1539 [ \pred_edit_or_source_button(Head, Options), 1540 &(nbsp) 1541 ]), 1542 a(name=Name, \pred_head(Head)) 1543 ]), 1544 { Done = [PI|Done0] } 1545 ). 1546 1547 (Head, Options) --> 1549 { option(edit(true), Options) }, 1550 !, 1551 pred_edit_button(Head, Options). 1552pred_edit_or_source_button(Head, Options) --> 1553 { option(source_link(true), Options) }, 1554 !, 1555 pred_source_button(Head, Options). 1556pred_edit_or_source_button(_, _) --> [].
1570pred_edit_button(_, Options) --> 1571 { \+ option(edit(true), Options) }, 1572 !. 1573pred_edit_button(PI0, Options0) --> 1574 { canonicalise_predref(PI0, PI, Options0, Options) }, 1575 pred_edit_button2(PI, Options). 1576 (Name/Arity, Options) --> 1578 { \+ ( memberchk(file(_), Options), % always edit if file and line 1579 memberchk(line(_), Options) % are given. 1580 ), 1581 functor(Head, Name, Arity), 1582 option(module(M), Options, _), 1583 \+ ( current_module(M), 1584 source_file(M:Head, _File) 1585 ) 1586 }, 1587 !. 1588pred_edit_button2(Name/Arity, Options) --> 1589 { include(edit_param, Options, Extra), 1590 http_link_to_id(pldoc_edit, 1591 [name(Name),arity(Arity)|Extra], 1592 EditHREF) 1593 }, 1594 html(a(onClick('HTTPrequest(\'' + EditHREF + '\')'), 1595 img([ class(action), 1596 alt('Edit predicate'), 1597 title('Edit predicate'), 1598 src(location_by_id(pldoc_resource)+'editpred.png') 1599 ]))). 1600pred_edit_button2(_, _) --> 1601 !, 1602 []. 1603 1604edit_param(module(_)). 1605edit_param(file(_)). 1606edit_param(line(_)).
1613object_edit_button(_, Options) --> 1614 { \+ option(edit(true), Options) }, 1615 !. 1616object_edit_button(PI, Options) --> 1617 { is_pi(PI) }, 1618 !, 1619 pred_edit_button(PI, Options). 1620object_edit_button(_, _) --> 1621 [].
1628pred_source_button(PI0, Options0) --> 1629 { canonicalise_predref(PI0, PI, Options0, Options), 1630 option(module(M), Options, _), 1631 pred_source_href(PI, M, HREF), ! 1632 }, 1633 html(a([ href(HREF) 1634 ], 1635 img([ class(action), 1636 alt('Source'), 1637 title('Show source'), 1638 src(location_by_id(pldoc_resource)+'source.png') 1639 ]))). 1640pred_source_button(_, _) --> 1641 [].
1648object_source_button(PI, Options) --> 1649 { is_pi(PI), 1650 option(source_link(true), Options, true) 1651 }, 1652 !, 1653 pred_source_button(PI, Options). 1654object_source_button(_, _) --> 1655 [].
module(M) to Options.1663canonicalise_predref(M:PI0, PI, Options0, [module(M)|Options]) :- 1664 !, 1665 canonicalise_predref(PI0, PI, Options0, Options). 1666canonicalise_predref(//(Head), PI, Options0, Options) :- 1667 !, 1668 functor(Head, Name, Arity), 1669 PredArity is Arity + 2, 1670 canonicalise_predref(Name/PredArity, PI, Options0, Options). 1671canonicalise_predref(Name//Arity, PI, Options0, Options) :- 1672 integer(Arity), Arity >= 0, 1673 !, 1674 PredArity is Arity + 2, 1675 canonicalise_predref(Name/PredArity, PI, Options0, Options). 1676canonicalise_predref(PI, PI, Options, Options) :- 1677 PI = Name/Arity, 1678 atom(Name), integer(Arity), Arity >= 0, 1679 !. 1680canonicalise_predref(Head, PI, Options0, Options) :- 1681 functor(Head, Name, Arity), 1682 canonicalise_predref(Name/Arity, PI, Options0, Options).
span using
class pred and the arguments and var using class arglist.1690pred_head(Var) --> 1691 { var(Var), 1692 !, 1693 instantiation_error(Var) 1694 }. 1695pred_head(//(Head)) --> 1696 !, 1697 pred_head(Head), 1698 html(//). 1699pred_head(M:Head) --> 1700 html([span(class=module, M), :]), 1701 pred_head(Head). 1702pred_head(Head) --> 1703 { atom(Head) }, 1704 !, 1705 html(b(class=pred, Head)). 1706pred_head(Head) --> % Infix operators 1707 { Head =.. [Functor,Left,Right], 1708 is_op_type(Functor, infix) 1709 }, 1710 !, 1711 html([ var(class=arglist, \pred_arg(Left, 1)), 1712 ' ', b(class=pred, Functor), ' ', 1713 var(class=arglist, \pred_arg(Right, 2)) 1714 ]). 1715pred_head(Head) --> % Prefix operators 1716 { Head =.. [Functor,Arg], 1717 is_op_type(Functor, prefix) 1718 }, 1719 !, 1720 html([ b(class=pred, Functor), ' ', 1721 var(class=arglist, \pred_arg(Arg, 1)) 1722 ]). 1723pred_head(Head) --> % Postfix operators 1724 { Head =.. [Functor,Arg], 1725 is_op_type(Functor, postfix) 1726 }, 1727 !, 1728 html([ var(class=arglist, \pred_arg(Arg, 1)), 1729 ' ', b(class=pred, Functor) 1730 ]). 1731pred_head({Head}) --> 1732 !, 1733 html([ b(class=pred, '{'), 1734 var(class=arglist, 1735 \pred_args([Head], 1)), 1736 b(class=pred, '}') 1737 ]). 1738pred_head(Head) --> % Plain terms 1739 { Head =.. [Functor|Args] }, 1740 html([ b(class=pred, Functor), 1741 var(class=arglist, 1742 [ '(', \pred_args(Args, 1), ')' ]) 1743 ]).
prefix,
infix or postfix.1750is_op_type(Functor, Type) :- 1751 current_op(_Pri, F, Functor), 1752 op_type(F, Type). 1753 1754op_type(fx, prefix). 1755op_type(fy, prefix). 1756op_type(xf, postfix). 1757op_type(yf, postfix). 1758op_type(xfx, infix). 1759op_type(xfy, infix). 1760op_type(yfx, infix). 1761op_type(yfy, infix). 1762 1763 1764pred_args([], _) --> 1765 []. 1766pred_args([H|T], I) --> 1767 pred_arg(H, I), 1768 ( {T==[]} 1769 -> [] 1770 ; html(', '), 1771 { I2 is I + 1 }, 1772 pred_args(T, I2) 1773 ). 1774 1775pred_arg(Var, I) --> 1776 { var(Var) }, 1777 !, 1778 html(['Arg', I]). 1779pred_arg(...(Term), I) --> 1780 !, 1781 pred_arg(Term, I), 1782 html('...'). 1783pred_arg(Term, I) --> 1784 { Term =.. [Ind,Arg], 1785 mode_indicator(Ind) 1786 }, 1787 !, 1788 html([Ind, \pred_arg(Arg, I)]). 1789pred_arg(Arg:Type, _) --> 1790 !, 1791 html([\argname(Arg), :, \argtype(Type)]). 1792pred_arg(Arg, _) --> 1793 argname(Arg). 1794 1795argname('$VAR'(Name)) --> 1796 !, 1797 html(Name). 1798argname(Name) --> 1799 !, 1800 html(Name). 1801 1802argtype(Term) --> 1803 { format(string(S), '~W', 1804 [ Term, 1805 [ quoted(true), 1806 numbervars(true) 1807 ] 1808 ]) }, 1809 html(S). 1810 1811pred_det(unknown) --> 1812 []. 1813pred_det(Det) --> 1814 html([' is ', b(class=det, Det)]).
doc_wiki.pl.
1823term(_, Atom, []) --> 1824 { atomic(Atom), 1825 !, 1826 format(string(S), '~W', [Atom,[quoted(true)]]) 1827 }, 1828 html(span(class=functor, S)). 1829term(_, Key:Type, [TypeName=Type]) --> 1830 { atomic(Key) 1831 }, 1832 !, 1833 html([span(class='pl-key', Key), :, span(class('pl-var'), TypeName)]). 1834term(_, Term, Bindings) --> 1835 { is_mode(Term is det), % HACK. Bit too strict? 1836 bind_vars(Bindings) 1837 }, 1838 !, 1839 pred_head(Term). 1840term(_, Term, Bindings) --> 1841 term(Term, 1842 [ variable_names(Bindings), 1843 quoued(true) 1844 ]). 1845 1846 1847 /******************************* 1848 * PREDREF * 1849 *******************************/
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.
1862predref(Term) --> 1863 { catch(nb_getval(pldoc_options, Options), _, Options = []) }, 1864 predref(Term, Options). 1865 1866predref(Obj, Options) --> 1867 { Obj = _:_, 1868 doc_comment(Obj, File:_Line, _, _), 1869 ( ( option(files(Map), Options) 1870 -> memberchk(file(File,_), Map) 1871 ; true 1872 ) 1873 -> object_href(Obj, HREF, Options) 1874 ; manref(Obj, HREF, Options) 1875 ) 1876 }, 1877 !, 1878 html(a(href(HREF), \object_name(Obj, [qualify(true)|Options]))). 1879predref(M:Term, Options) --> 1880 !, 1881 predref(Term, M, Options). 1882predref(Term, Options) --> 1883 predref(Term, _, Options). 1884 1885predref(Name/Arity, _, Options) --> % Builtin; cannot be overruled 1886 { prolog:doc_object_summary(Name/Arity, manual, _, _), 1887 !, 1888 manref(Name/Arity, HREF, Options) 1889 }, 1890 html(a([class=builtin, href=HREF], [Name, /, Arity])). 1891predref(Name/Arity, _, Options) --> % From packages 1892 { option(prefer(manual), Options), 1893 prolog:doc_object_summary(Name/Arity, Category, _, _), 1894 !, 1895 manref(Name/Arity, HREF, Options) 1896 }, 1897 html(a([class=Category, href=HREF], [Name, /, Arity])). 1898predref(Obj, Module, Options) --> % Local 1899 { doc_comment(Module:Obj, File:_Line, _, _), 1900 ( option(files(Map), Options) 1901 -> memberchk(file(File,_), Map) 1902 ; true 1903 ) 1904 }, 1905 !, 1906 object_ref(Module:Obj, Options). 1907predref(Name/Arity, Module, Options) --> 1908 { \+ option(files(_), Options), 1909 pred_href(Name/Arity, Module, HREF) 1910 }, 1911 !, 1912 html(a(href=HREF, [Name, /, Arity])). 1913predref(Name//Arity, Module, Options) --> 1914 { \+ option(files(_), Options), 1915 PredArity is Arity + 2, 1916 pred_href(Name/PredArity, Module, HREF) 1917 }, 1918 !, 1919 html(a(href=HREF, [Name, //, Arity])). 1920predref(PI, _, Options) --> % From packages 1921 { canonical_pi(PI, CPI, HTML), 1922 ( option(files(_), Options) 1923 -> Category = extmanual 1924 ; prolog:doc_object_summary(CPI, Category, _, _) 1925 ), 1926 manref(CPI, HREF, Options) 1927 }, 1928 html(a([class=Category, href=HREF], HTML)). 1929predref(PI, _, _Options) --> 1930 { canonical_pi(PI, _CPI, HTML) 1931 }, 1932 !, 1933 html(span(class=undef, HTML)). 1934predref(Callable, Module, Options) --> 1935 { callable(Callable), 1936 functor(Callable, Name, Arity) 1937 }, 1938 predref(Name/Arity, Module, Options). 1939 1940canonical_pi(Name/Arity, Name/Arity, [Name, /, Arity]) :- 1941 atom(Name), integer(Arity), 1942 !. 1943canonical_pi(Name//Arity, Name/Arity2, [Name, //, Arity]) :- 1944 atom(Name), integer(Arity), 1945 !, 1946 Arity2 is Arity+2.
name/arity, non-linking predicate indicator.
1952nopredref(PI) -->
1953 { canonical_pi(PI, _CPI, HTML)
1954 },
1955 !,
1956 html(span(class=nopredref, HTML)).
1964flagref(Flag) -->
1965 html(code(Flag)).1972cite(Citations) --> 1973 html('['), citations(Citations), html(']'). 1974 1975citations([]) --> []. 1976citations([H|T]) --> 1977 citation(H), 1978 ( {T==[]} 1979 -> [] 1980 ; [';'], 1981 citations(T) 1982 ). 1983 1984citation(H) --> 1985 html([@,H]).
man_server(+Server).1993manref(PI, HREF, Options) :- 1994 predname(PI, PredName), 1995 ( option(files(_Map), Options) 1996 -> option(man_server(Server), Options, 1997 'http://www.swi-prolog.org/pldoc'), 1998 uri_components(Server, Comp0), 1999 uri_data(path, Comp0, Path0), 2000 directory_file_path(Path0, man, Path), 2001 uri_data(path, Comp0, Path, Components), 2002 uri_query_components(Query, [predicate=PredName]), 2003 uri_data(search, Components, Query), 2004 uri_components(HREF, Components) 2005 ; http_link_to_id(pldoc_man, [predicate=PredName], HREF) 2006 ). 2007 2008predname(Name/Arity, PredName) :- 2009 !, 2010 format(atom(PredName), '~w/~d', [Name, Arity]). 2011predname(Module:Name/Arity, PredName) :- 2012 !, 2013 format(atom(PredName), '~w:~w/~d', [Module, Name, Arity]).
2027pred_href(Name/Arity, Module, HREF) :- 2028 format(string(FragmentId), '~w/~d', [Name, Arity]), 2029 uri_data(fragment, Components, FragmentId), 2030 functor(Head, Name, Arity), 2031 ( catch(relative_file(Module:Head, File), _, fail) 2032 -> uri_data(path, Components, File), 2033 uri_components(HREF, Components) 2034 ; in_file(Module:Head, File) 2035 -> ( current_prolog_flag(home, SWI), 2036 sub_atom(File, 0, _, _, SWI), 2037 prolog:doc_object_summary(Name/Arity, packages, _, _) 2038 -> http_link_to_id(pldoc_man, [predicate=FragmentId], HREF) 2039 ; http_location_by_id(pldoc_doc, DocHandler), 2040 atom_concat(DocHandler, File, Path), 2041 uri_data(path, Components, Path), 2042 uri_components(HREF, Components) 2043 ) 2044 ). 2045 2046relative_file(Head, '') :- 2047 b_getval(pldoc_file, CurrentFile), CurrentFile \== [], 2048 in_file(Head, CurrentFile), 2049 !. 2050relative_file(Head, RelFile) :- 2051 b_getval(pldoc_file, CurrentFile), CurrentFile \== [], 2052 in_file(Head, DefFile), 2053 relative_file_name(DefFile, CurrentFile, RelFile).
2059pred_source_href(Name/Arity, Module, HREF) :-
2060 format(string(FragmentId), '~w/~d', [Name, Arity]),
2061 uri_data(fragment, Components, FragmentId),
2062 uri_query_components(Query, [show=src]),
2063 uri_data(search, Components, Query),
2064 functor(Head, Name, Arity),
2065 ( catch(relative_file(Module:Head, File), _, fail)
2066 -> uri_data(path, Components, File),
2067 uri_components(HREF, Components)
2068 ; in_file(Module:Head, File0)
2069 -> insert_alias(File0, File),
2070 http_location_by_id(pldoc_doc, DocHandler),
2071 atom_concat(DocHandler, File, Path),
2072 uri_data(path, Components, Path),
2073 uri_components(HREF, Components)
2074 ).2083object_ref([], _) --> 2084 !, 2085 []. 2086object_ref([H|T], Options) --> 2087 !, 2088 object_ref(H, Options), 2089 ( {T == []} 2090 -> html(', '), 2091 object_ref(T, Options) 2092 ; [] 2093 ). 2094object_ref(Obj, Options) --> 2095 { object_href(Obj, HREF, Options) 2096 }, 2097 html(a(href(HREF), \object_name(Obj, Options))).
2104object_href(Obj, HREF) :- 2105 object_href(Obj, HREF, []). 2106 2107object_href(M:PI0, HREF, Options) :- 2108 option(files(Map), Options), 2109 ( module_property(M, file(File)) 2110 -> true 2111 ; xref_module(File, M) 2112 ), 2113 memberchk(file(File, DocFile), Map), 2114 !, 2115 file_base_name(DocFile, LocalFile), % TBD: proper directory index 2116 expand_pi(PI0, PI), 2117 term_to_string(PI, PIS), 2118 uri_data(path, Components, LocalFile), 2119 uri_data(fragment, Components, PIS), 2120 uri_components(HREF, Components). 2121object_href(file(File), HREF, _Options) :- 2122 doc_file_href(File, HREF), 2123 !. 2124object_href(directory(Dir), HREF, _Options) :- 2125 directory_file_path(Dir, 'index.html', Index), 2126 doc_file_href(Index, HREF), 2127 !. 2128object_href(Obj, HREF, _Options) :- 2129 prolog:doc_object_href(Obj, HREF), 2130 !. 2131object_href(Obj0, HREF, _Options) :- 2132 localise_object(Obj0, Obj), 2133 term_to_string(Obj, String), 2134 http_link_to_id(pldoc_object, [object=String], HREF). 2135 2136expand_pi(Name//Arity0, Name/Arity) :- 2137 !, 2138 Arity is Arity0+2. 2139expand_pi(PI, PI).
2147localise_object(Obj0, Obj) :- 2148 prolog:doc_canonical_object(Obj0, Obj), 2149 !. 2150localise_object(Obj, Obj).
2158term_to_string(Term, String) :-
2159 State = state(-),
2160 ( numbervars(Term, 0, _, [singletons(true)]),
2161 with_output_to(string(String),
2162 write_term(Term,
2163 [ numbervars(true),
2164 quoted(true)
2165 ])),
2166 nb_setarg(1, State, String),
2167 fail
2168 ; arg(1, State, String)
2169 ).inline or titlenumber, title or number_title2183object_name(Obj, Options) --> 2184 { option(style(Style), Options, inline) 2185 }, 2186 object_name(Style, Obj, Options). 2187 2188object_name(title, Obj, Options) --> 2189 { merge_options(Options, [secref_style(title)], Options1) }, 2190 prolog:doc_object_link(Obj, Options1), 2191 !. 2192object_name(inline, Obj, Options) --> 2193 prolog:doc_object_link(Obj, Options), 2194 !. 2195object_name(title, f(Name/Arity), _Options) --> 2196 !, 2197 html(['Function ', Name, /, Arity]). 2198object_name(inline, f(Name/Arity), _Options) --> 2199 !, 2200 html([Name, /, Arity]). 2201object_name(Style, PI, Options) --> 2202 { is_pi(PI) }, 2203 !, 2204 pi(Style, PI, Options). 2205object_name(inline, Module:module(_Title), _) --> 2206 !, 2207 { module_property(Module, file(File)), 2208 file_base_name(File, Base) 2209 }, 2210 !, 2211 html(Base). 2212object_name(title, Module:module(Title), _) --> 2213 { module_property(Module, file(File)), 2214 file_base_name(File, Base) 2215 }, 2216 !, 2217 html([Base, ' -- ', Title]). 2218object_name(title, file(File), _) --> 2219 { module_property(Module, file(File)), 2220 doc_comment(Module:module(Title), _, _, _), 2221 !, 2222 file_base_name(File, Base) 2223 }, 2224 html([Base, ' -- ', Title]). 2225object_name(_, file(File), _) --> 2226 { file_base_name(File, Base) }, 2227 html(Base). 2228object_name(_, directory(Dir), _) --> 2229 { file_base_name(Dir, Base) }, 2230 html(Base). 2231object_name(_, module(Title), _Options) --> 2232 { print_message(warning, 2233 pldoc(module_comment_outside_module(Title))) 2234 }. 2235 2236pi(title, PI, Options) --> 2237 pi_type(PI), 2238 pi(PI, Options). 2239pi(inline, PI, Options) --> 2240 pi(PI, Options). 2241 2242pi(M:PI, Options) --> 2243 !, 2244 ( { option(qualify(true), Options) } 2245 -> html([span(class(module), M), :]) 2246 ; [] 2247 ), 2248 pi(PI, Options). 2249pi(Name/Arity, _) --> 2250 !, 2251 html([Name, /, Arity]). 2252pi(Name//Arity, _) --> 2253 html([Name, //, Arity]). 2254 2255pi_type(_:PI) --> 2256 !, 2257 pi_type(PI). 2258pi_type(_/_) --> 2259 html(['Predicate ']). 2260pi_type(_//_) --> 2261 html(['Grammar rule ']).
2273in_file(Module:Head, File) :- 2274 !, 2275 distinct(File, in_file(Module, Head, File)). 2276in_file(Head, File) :- 2277 distinct(File, in_file(_, Head, File)). 2278 2279in_file(Module, Head, File) :- 2280 var(Module), 2281 ( predicate_property(system:Head, foreign) 2282 -> !, 2283 fail 2284 ; predicate_property(system:Head, file(File)), 2285 \+ system_arithmetic_function(Head) 2286 -> ! 2287 ; predicate_property(Head, autoload(File0)) 2288 -> !, 2289 file_name_extension(File0, pl, File) 2290 ; exported_from(Module, Head, File), 2291 module_property(Module, class(library)) 2292 ). 2293in_file(Module, Head, File) :- 2294 nonvar(Module), 2295 predicate_property(Module:Head, file(File)), 2296 \+ predicate_property(Module:Head, imported_from(_)). 2297in_file(Module, Head, File) :- 2298 xref_defined(File, Head, How), 2299 xref_current_source(File), 2300 atom(File), % only plain files 2301 xref_module(File, Module), 2302 How \= imported(_From). 2303in_file(Module, Head, File) :- 2304 exported_from(Module, Head, File). 2305in_file(Module, Head, File) :- 2306 predicate_property(Module:Head, file(File)), 2307 \+ predicate_property(Module:Head, imported_from(_)). 2308in_file(Module, Head, File) :- 2309 current_module(Module), 2310 source_file(Module:Head, File). 2311 2312exported_from(Module, Head, File) :- 2313 distinct(Primary, 2314 ( predicate_property(Module:Head, exported), 2315 ( predicate_property(Module:Head, imported_from(Primary)) 2316 -> true 2317 ; Primary = Module 2318 ))), 2319 module_property(Primary, file(File)). 2320 2321:- multifile 2322 arithmetic:evaluable/2. 2323 2324system_arithmetic_function(Head) :- 2325 functor(Head, Name, Arity), 2326 FArith is Arity-1, 2327 FArith >= 0, 2328 functor(FHead, Name, FArith), 2329 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.2360file(File) --> 2361 file(File, []). 2362 2363file(File, Options) --> 2364 { catch(nb_getval(pldoc_options, GenOptions), _, GenOptions = []), 2365 merge_options(Options, GenOptions, FinalOptions) 2366 }, 2367 link_file(File, FinalOptions), 2368 !. 2369file(File, Options) --> 2370 { option(edit_handler(Handler), Options), 2371 http_current_request(Request), 2372 memberchk(path(Path), Request), 2373 absolute_file_name(File, Location, 2374 [ relative_to(Path) 2375 ]), 2376 http_link_to_id(Handler, [location(Location)], HREF), 2377 format(atom(Title), 'Click to create ~w', [File]) 2378 }, 2379 html(a([href(HREF), class(nofile), title(Title)], File)). 2380file(File, _) --> 2381 html(code(class(nofile), File)). 2382 2383link_file(File, Options) --> 2384 { file_href(File, HREF, Options), 2385 option(label(Label), Options, File), 2386 option(class(Class), Options, file) 2387 }, 2388 html(a([class(Class), href(HREF)], Label)).
2394file_href(_, HREF, Options) :- 2395 option(href(HREF), Options), 2396 !. 2397file_href(File, HREF, Options) :- 2398 file_href_real(File, HREF0, Options), 2399 map_extension(HREF0, HREF, Options).
map_extension(+Pairs)2407map_extension(HREF0, HREF, Options) :- 2408 option(map_extension(Map), Options), 2409 file_name_extension(Base, Old, HREF0), 2410 memberchk(Old-New, Map), 2411 !, 2412 file_name_extension(Base, New, HREF). 2413map_extension(HREF, HREF, _). 2414 2415 2416file_href_real(File, HREF, Options) :- 2417 ( option(absolute_path(Path), Options) 2418 ; existing_linked_file(File, Path) 2419 ), 2420 !, 2421 ( option(files(Map), Options), 2422 memberchk(file(Path, LinkFile), Map) 2423 -> true 2424 ; LinkFile = Path 2425 ), 2426 file_href(LinkFile, HREF). 2427file_href_real(File, HREF, _) :- 2428 directory_alias(Alias), 2429 Term =.. [Alias,File], 2430 absolute_file_name(Term, _, 2431 [ access(read), 2432 file_errors(fail) 2433 ]), 2434 !, 2435 http_absolute_location(Term, HREF, []). 2436 2437directory_alias(icons). 2438directory_alias(css).
pldoc_file.2448file_href(Path, HREF) :- % a loaded Prolog file 2449 source_file(Path), 2450 !, 2451 doc_file_href(Path, HREF). 2452file_href(Path, HREF) :- 2453 ( nb_current(pldoc_output, CFile) 2454 ; nb_current(pldoc_file, CFile) 2455 ), 2456 CFile \== [], 2457 !, 2458 relative_file_name(Path, CFile, HREF). 2459file_href(Path, Path).
2467existing_linked_file(File, Path) :-
2468 catch(b_getval(pldoc_file, CurrentFile), _, fail),
2469 CurrentFile \== [],
2470 absolute_file_name(File, Path,
2471 [ relative_to(CurrentFile),
2472 access(read),
2473 file_errors(fail)
2474 ]).include(File,
Type) terms in the DOM term generated by wiki.pl if it
encounters [[file.ext]].2484include(PI, predicate, _) --> 2485 !, 2486 ( html_tokens_for_predicates(PI, []) 2487 -> [] 2488 ; html(['[[', \predref(PI), ']]']) 2489 ). 2490include(File, image, Options) --> 2491 { file_name_extension(_, svg, File), 2492 file_href(File, HREF, Options), 2493 !, 2494 include(image_attribute, Options, Attrs0), 2495 merge_options(Attrs0, 2496 [ alt(File), 2497 data(HREF), 2498 type('image/svg+xml') 2499 ], Attrs) 2500 }, 2501 ( { option(caption(Caption), Options) } 2502 -> html(div(class(figure), 2503 [ div(class(image), object(Attrs, [])), 2504 div(class(caption), Caption) 2505 ])) 2506 ; html(object(Attrs, [])) 2507 ). 2508include(File, image, Options) --> 2509 { file_href(File, HREF, Options), 2510 !, 2511 include(image_attribute, Options, Attrs0), 2512 merge_options(Attrs0, 2513 [ alt(File), 2514 border(0), 2515 src(HREF) 2516 ], Attrs) 2517 }, 2518 ( { option(caption(Caption), Options) } 2519 -> html(div(class(figure), 2520 [ div(class(image), img(Attrs)), 2521 div(class(caption), Caption) 2522 ])) 2523 ; html(img(Attrs)) 2524 ). 2525include(File, wiki, _Options) --> % [[file.txt]] is included 2526 { access_file(File, read), 2527 !, 2528 read_file_to_codes(File, String, []), 2529 wiki_codes_to_dom(String, [], DOM) 2530 }, 2531 html(DOM). 2532include(File, _Type, Options) --> 2533 link_file(File, Options), 2534 !. 2535include(File, _, _) --> 2536 html(code(class(nofile), ['[[',File,']]'])). 2537 2538image_attribute(src(_)). 2539image_attribute(alt(_)). 2540image_attribute(title(_)). 2541image_attribute(align(_)). 2542image_attribute(width(_)). 2543image_attribute(height(_)). 2544image_attribute(border(_)). 2545image_attribute(class(_)). 2546image_attribute(style(_)).
* [[member/2]]
* [[append/3]]
2559html_tokens_for_predicates([], _Options) --> 2560 []. 2561html_tokens_for_predicates([H|T], Options) --> 2562 !, 2563 html_tokens_for_predicates(H, Options), 2564 html_tokens_for_predicates(T, Options). 2565html_tokens_for_predicates(PI, Options) --> 2566 { PI = _:_/_, 2567 !, 2568 ( doc_comment(PI, Pos, _Summary, Comment) 2569 -> true 2570 ; Comment = '' 2571 ) 2572 }, 2573 object(PI, [Pos-Comment], [dl], _, Options). 2574html_tokens_for_predicates(Spec, Options) --> 2575 { findall(PI, documented_pi(Spec, PI), List), 2576 List \== [], ! 2577 }, 2578 html_tokens_for_predicates(List, Options). 2579html_tokens_for_predicates(Spec, Options) --> 2580 man_page(Spec, 2581 [ links(false), % no header 2582 navtree(false), % no navigation tree 2583 footer(false), % no footer 2584 synopsis(false) % no synopsis 2585 | Options 2586 ]). 2587 2588 2589documented_pi(Spec, PI) :- 2590 generalise_spec(Spec, PI), 2591 doc_comment(PI, _Pos, _Summary, _Comment). 2592 2593generalise_spec(Name/Arity, _M:Name/Arity). 2594generalise_spec(Name//Arity, _M:Name//Arity). 2595 2596 2597 /******************************* 2598 * WIKI FILES * 2599 *******************************/
2606doc_for_wiki_file(FileSpec, Options) :- 2607 absolute_file_name(FileSpec, File, 2608 [ access(read) 2609 ]), 2610 read_file_to_codes(File, String, []), 2611 b_setval(pldoc_file, File), 2612 call_cleanup(reply_wiki_page(File, String, Options), 2613 nb_delete(pldoc_file)). 2614 2615reply_wiki_page(File, String, Options) :- 2616 wiki_codes_to_dom(String, [], DOM0), 2617 title(DOM0, File, Title), 2618 insert_edit_button(DOM0, File, DOM, Options), 2619 reply_html_page(pldoc(wiki), 2620 title(Title), 2621 [ \html_requires(pldoc) 2622 | DOM 2623 ]). 2624 2625title(DOM, _, Title) :- 2626 sub_term(h1(_,Title), DOM), 2627 !. 2628title(_, File, Title) :- 2629 file_base_name(File, Title). 2630 (DOM, _, DOM, Options) :- 2632 option(edit(false), Options, false), 2633 !. 2634insert_edit_button([h1(Attrs,Title)|DOM], File, 2635 [h1(Attrs,[ span(style('float:right'), 2636 \edit_button(File, [edit(true)])) 2637 | Title 2638 ])|DOM], _) :- !. 2639insert_edit_button(DOM, File, 2640 [ h1(class(wiki), 2641 [ span(style('float:right'), 2642 \edit_button(File, [edit(true)])) 2643 ]) 2644 | DOM 2645 ], _). 2646 2647 2648 /******************************* 2649 * ANCHORS * 2650 *******************************/
2656mode_anchor_name(Var, _) :- 2657 var(Var), 2658 !, 2659 instantiation_error(Var). 2660mode_anchor_name(mode(Head, _), Anchor) :- 2661 !, 2662 mode_anchor_name(Head, Anchor). 2663mode_anchor_name(Head is _Det, Anchor) :- 2664 !, 2665 mode_anchor_name(Head, Anchor). 2666mode_anchor_name(Head, Anchor) :- 2667 pred_anchor_name(Head, _, Anchor).
2674pred_anchor_name(//(Head), Name/Arity, Anchor) :- 2675 !, 2676 functor(Head, Name, DCGArity), 2677 Arity is DCGArity+2, 2678 format(atom(Anchor), '~w/~d', [Name, Arity]). 2679pred_anchor_name(Head, Name/Arity, Anchor) :- 2680 functor(Head, Name, Arity), 2681 format(atom(Anchor), '~w/~d', [Name, Arity]). 2682 2683:- multifile prolog:message//1. 2684 2685prologmessage(pldoc(module_comment_outside_module(Title))) --> 2686 [ '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.plinto HTML+CSS.