Pldoc predicate ordering

I’m in the process of adding pldoc to a module and I’m struggling with the order in which the exported predicates appear in the doc. Basic scenario: I have a module with fairly long export list. About half the exported predciates are documented and implemented in the main module file and the remaining are documented/implemented in an included file.

The generated doc provides the module file predicates in the order in which the predicates appear in the source, which is fine. However, those in the included file are separated out into a re-export list and appear in pretty much random order. This appears to be because the so-called re-exported predicates are derived from the module property exports list which lists the exported predicates in pretty much random order as far as I can tell. This is not helpful, e.g., two related predicates (same functor, different arity) are not co-located.

So is there anything I can do to fix this without mangling the code structure (re-arranging doc source)? I could live with either the order in which they appear in the module’s actual export list or the order in which they appear in the source (assuming include = embed).

I’m also not sure why predicates in included files are deemed re-exported. It’s just an artifact of how the module is internally structured (not normally visible to the user); they don’t come from any other module.

You can (and should) export predicates from included files using the normal module header. I don’t understand how you combine include/1 and reexport/1,2 anyway. reexport/1,2 is basically use_module/1,2 and export/1 for the predicates imported. It was added when Vitor and I discussed portability as an easy way to create a somewhat modified version of a library. In application code I tend to simple add the re-exported predicates explicitly to the module header, i.e., use normal use_module/1, as in

:- module(m, [p/1, q/1]).

:- use_module(helper, [q/1]).  % or use_module(helper)

p(X) :-

Ordering of documentation for predicates that are not in the same file is indeed an issue. Possibly we can “fix” the order by considering all the predicates that come from some other file to appear at the location this file has been included/imported? I think that would be doable. But then, typically, while you tend to include/import code at the top, I have the impression you often would like the documentation to be near the end as they are often “support” predicates.

A totally different way might be to allow documenting the whole thing in the module header. PlDoc’s markdown already allows for including the full doc of a predicate using a list like this

   - [[p/1]]
   - [[q/2]]
   ...

So, if we hide generating the documentation of predicates that were already included into the module description using the construct above, we get what we want.

Another thing I always wanted is a way to have text blocks between sets of predicates. We could achieve that using e.g.

/** <section> Title
 
Bla bla
*/

Alternative to <section> we could have something more neutral and have the user using normal ## title markdown inside. No what <...> to use for that though.

Comments?

I can (and do) export predicates this way. There is no re-export or using; just the predicate definitions (and pldoc, as suggested) are in a separate “included” file. I think of include as a purely syntactic replacement, i.e., just replace the directive with the text from the included file, i.e., flatten the text. So not the same as importing which, to me, is a quite different story.

I think this is the real focus. With respect to including, I may be wrong, but it appears that when the html is generated, the pldoc/4 containing the doc has been asserted in the module context in the order in which it appeared in the flattened source. So couldn’t that order be used?

Possibly. As is, I think the ordering is based on line numbers (could be incorrect), so the predicates of the included and main file get interleaved. The alternative would be to create a sort key that is based on a combination of the location of the include/1 directive (I think you get that from source_file_property/2) and the predicate line number. I guess that expressing the location as a list that start with the line number of the outermost include/1 and ends with the actual line number of the predicate will do.

If you sort out something sensible, I’m happy to merge.

I’ve tested a minimal solution localized to pldoc_html:undocumented//3, that satisfies my immediate needs. It just sorts any “re-exported doc” objects according to their position (File name and line number) and seems to group and order the predicates nicely. If that’s acceptable I’ll generate a PR on the pldoc package.

I still have a philosophical quibble with considering included predicate definitions as “re-exported”, but that can be a separate discussion if there’s any interest.

Sounds like an improvement :slight_smile: