36
37:- module(pldoc_files,
38 [ doc_save/2, 39 doc_pack/1 40 ]). 41:- use_module(library(pldoc), []). 42:- use_module(pldoc(doc_html)). 43:- use_module(pldoc(doc_index)). 44:- use_module(pldoc(doc_pack)). 45:- use_module(library(option)). 46:- use_module(library(lists)). 47:- use_module(library(filesex)).
60:- predicate_options(doc_save/2, 2,
61 [ format(oneof([html])),
62 doc_root(atom),
63 man_server(atom),
64 index_file(atom),
65 if(oneof([loaded,true])),
66 recursive(boolean),
67 css(oneof([copy,inline])),
68 title(atom),
69 include_reexported(boolean)
70 ]).
128
129doc_save(Spec, Options) :-
130 doc_target(Spec, Target, Options),
131 target_directory(Target, Dir),
132 phrase(file_map(Target), FileMap),
133 merge_options([ html_resources(pldoc_files),
134 source_link(false),
135 resource_directory(Dir)
136 ], Options, Options1),
137 Options2 = [files(FileMap)|Options1],
138 setup_call_cleanup(
139 nb_setval(pldoc_options, Options2),
140 generate(Target, Options2),
141 nb_delete(pldoc_options)),
142 copy_resources(Dir, Options2).
150generate([], _).
151generate([H|T], Options) :-
152 \+ \+ generate(H, Options),
153 generate(T, Options).
154generate(file(PlFile, DocFile), Options) :-
155 b_setval(pldoc_output, DocFile),
156 setup_call_cleanup(
157 open(DocFile, write, Out, [encoding(utf8)]),
158 with_output_to(Out, doc_for_file(PlFile, Options)),
159 close(Out)).
160generate(directory(Dir, IndexFile, Members, DirOptions), Options) :-
161 append(DirOptions, Options, AllOptions),
162 b_setval(pldoc_output, IndexFile),
163 setup_call_cleanup(
164 open(IndexFile, write, Out, [encoding(utf8)]),
165 with_output_to(
166 Out,
167 doc_for_dir(Dir,
168 [ members(Members)
169 | AllOptions
170 ])),
171 close(Out)),
172 generate(Members, Options).
187doc_target(FileOrDir, file(File, DocFile), Options) :-
188 absolute_file_name(FileOrDir, File,
189 [ file_type(prolog),
190 file_errors(fail),
191 access(read)
192 ]),
193 !,
194 ( option(source_root(_), Options)
195 -> Options1 = Options
196 ; file_directory_name(File, FileDir),
197 Options1 = [source_root(FileDir)|Options]
198 ),
199 document_file(File, DocFile, Options1).
200doc_target(FileOrDir, directory(Dir, Index, Members, DirOptions), Options0) :-
201 absolute_file_name(FileOrDir, Dir,
202 [ file_type(directory),
203 file_errors(fail),
204 access(read)
205 ]),
206 !,
207 ( option(source_root(_), Options0) 208 -> Options = Options0
209 ; Options1 = [source_root(Dir)|Options0], 210 exclude(main_option, Options1, Options2),
211 set_doc_root(Dir, Options2, Options)
212 ),
213 DirOptions = Options,
214 document_file(Dir, Index, Options),
215 findall(Member,
216 ( prolog_file_in_dir(Dir, File, Options),
217 doc_target(File, Member, Options)
218 ),
219 Members).
225main_option(title(_)).
226main_option(readme(_)).
227main_option(todo(_)).
228
229target_directory(directory(_, Index, _, _), Dir) :-
230 file_directory_name(Index, Dir).
231target_directory(file(_, DocFile), Dir) :-
232 file_directory_name(DocFile, Dir).
233
234set_doc_root(_Dir, Options0, Options) :-
235 option(doc_root(_), Options0),
236 !,
237 Options = Options0.
238set_doc_root(Dir, Options0, Options) :-
239 directory_file_path(Dir, doc, DocRoot),
240 Options = [doc_root(DocRoot)|Options0].
247file_map([]) -->
248 [].
249file_map([H|T]) -->
250 file_map(H),
251 file_map(T).
252file_map(file(Src, Doc)) -->
253 [ file(Src, Doc) ].
254file_map(directory(_Dir, _Doc, Members, _Options)) -->
255 file_map(Members).
264document_file(FileOrDir, DocFile, Options) :-
265 must_document(FileOrDir, Options),
266 option(format(Format), Options, html),
267 doc_extension(Format, Ext),
268 ( exists_directory(FileOrDir)
269 -> option(index_file(IndexBase), Options, index),
270 file_name_extension(IndexBase, Ext, Index),
271 directory_file_path(FileOrDir, Index, DocFile0)
272 ; file_name_extension(Base, _, FileOrDir),
273 file_name_extension(Base, Ext, DocFile0)
274 ),
275 ( option(doc_root(Dir), Options)
276 -> ( option(source_root(SrcTop), Options)
277 -> true
278 ; working_directory(SrcTop, SrcTop)
279 ),
280 directory_file_path(SrcTop, Local, DocFile0),
281 directory_file_path(Dir, Local, DocFile),
282 file_directory_name(DocFile, DocDir),
283 make_directory_path(DocDir)
284 ; DocFile = DocFile0
285 ).
286
287must_document(_FileOrDir, Options) :-
288 \+ option(if(loaded), Options, loaded),
289 !.
290must_document(File, _Options) :-
291 source_file(File),
292 !.
293must_document(Dir, _Options) :-
294 exists_directory(Dir),
295 source_file(SrcFile),
296 sub_atom(SrcFile, 0, _, _, Dir),
297 !.
301doc_extension(html, html).
302doc_extension(latex, tex).
312prolog_file_in_dir(Dir, File, Options) :-
313 ( option(if(loaded), Options, loaded)
314 -> source_file(File),
315 file_directory_name(File, Dir)
316 ; user:prolog_file_type(Ext, prolog),
317 \+ user:prolog_file_type(Ext, qlf),
318 atomic_list_concat([Dir, '/*.', Ext], Pattern),
319 expand_file_name(Pattern, Files),
320 member(File, Files)
321 ),
322 file_base_name(File, Base),
323 \+ blocked(Base).
324prolog_file_in_dir(Dir, SubDir, Options) :-
325 option(recursive(true), Options, false),
326 option(doc_root(DocRoot), Options),
327 atom_concat(Dir, '/*', Pattern),
328 expand_file_name(Pattern, Matches),
329 member(SubDir, Matches),
330 SubDir \== DocRoot,
331 exists_directory(SubDir).
337blocked('INDEX.pl').
338
339
340
346copy_resources(Dir, Options) :-
347 option(format(Format), Options, html),
348 forall(doc_resource(Format, Res),
349 ( absolute_file_name(pldoc(Res), File, [access(read)]),
350 copy_file(File, Dir))).
351
352doc_resource(html, 'pldoc.css').
353doc_resource(html, 'h1-bg.png').
354doc_resource(html, 'h2-bg.png').
355doc_resource(html, 'multi-bg.png').
356doc_resource(html, 'priv-bg.png').
357doc_resource(html, 'pub-bg.png')
Create stand-alone documentation files
Create stand-alone documentation from a bundle of source-files. Typical use of the PlDoc package is to run it as a web-server from the project in progress, providing search and guaranteed consistency with the loaded version. Creating stand-alone files as provided by this file can be useful for printing or distribution.