Using FORD documentation system

I used FORD for quite some time, but just for small projects. Recently, I decided to bite the bullet and write proper documentation for large projects, where I faced two problems. To be honest, the large problem here is to actually write the documentation itself: Everybody wants documentation, nobody wants to write it…
Anyway, I realize this is about FORD, not Fortran, but I guess the best place to ask is here, where more experienced FORD users than me might have a solution.

The first problem is processing time. In larger projects, FORD processing takes sometime, especially when generating graphs and search index. A sample project I used, with about 400 procedures, takes about 30 seconds to be processed . This is not too much, but imagine when you do it often - which you will, when writing documentation. Admittedly, none of my computers is a modern “beast”, but still, compiling large projects usually takes way less time than processing them with FORD.
Now, the only solution I can think is to skip generating graphs and search index until the documentation comments are written, and just enable those features in the end. But that’s far from being ideal. Is there any way to speed up FORD processing, perhaps by multithread it or something?

The second problem is private procedures. All my modules are declared as private, and public procedures are explicitly declared as such. Private procedures are typically used for internal implementation details and are not intended to be part of the public interface of a module. As such, they should not be documented in the generated documentation. So I would expect FORD to do the right thing here, and skip private procedures completely. But it doesn’t, at least not completely. It actually skips the details, but the private procedures are still mentioned in the resulting documentation, just without any information.
I can think of two ways to make FORD completely ignore private procedures: Either explicitly exclude them, or put them in a separate directory, which is explicitly ignored with exclude_dir in FORD’s project file options. I don’t find any of those solutions practical, because I will have to either list the excluded procedures one by one, or move them in another directory, just for FORD’s sake. Is there another way to completely skip private procedures in FORD?

Because they are called through generic interfaces? In this case it makes sense to add them. At least in my version of FORD (6.2.5), private procedure are not included, unless they are part of a generic interface.

Or, it could be a side effect of FORD option incl_src: true.

Actually yes, I should mention that before. They are indeed private procedures included in generic interfaces, but I still want them ignored, because they are actually bind(c) procedures, and documentation about them already exists (and it is surprisingly good) in the corresponding C library. And there are lots of them, so adding them in the exclude list one by one is not convenient.

Update: Although I couldn’t find a sane way to solve the problem with unwanted pseudo-documentation for private procedures, I could at least find a way to reduce processing time. It turns out FORD’s “search” functionality (which is turned on by default) can be created much faster if the lxml library is installed. You don’t really have to do anything in FORD itself to activate it, just install lxml. That alone makes processing much faster. lxml was available in the repositories of the *nix distributions I use, so I could easily install it, but I read it is also available in other platforms as well. If you use FORD, you should definitely install lxml as well.

As for the “graph” functionality, this is still slow in large projects. The only way I know to avoid this is to disable it while documentation is still written and tested, then just enable it again when documentation is done.

Are you familiar with FORD metadata lines? I always thought that was what the “display:” line
allowed you to control; but trying it for the first time it did not do exactly what I expected; but FORD being Open Source perhaps a few finer-grained behaviors could be added.

But I think the “display” and “source” metadata lines might still be of interest. You get different behaviors if you delete the metadata at the top for the module and just have it for the procedures;

module sample
!! author: Howard the Duck
!! version: v1.0
!! display: none
!! proc_internals: false
!! source: false
!!
!! the module
contains
subroutine quiet(a,b,c)
!! author: Howard the Duck
!! version: v1.0
!! display: none
!! proc_internals: false
!! source: false
!!
!! a quiet procedure
real,intent(in) :: a !! first option
real,intent(in) :: b !! second option
real,intent(in) :: c !! third option
!! do stuff
   write(*,*)a,b,c
end subroutine quiet
subroutine verbose(a,b,c)
!! author: Howard the Duck
!! version: v1.0
!! display: public private protected
!! proc_internals: true
!! source: true
!!
!! a verbose procedure
real,intent(in) :: a !! first option
real,intent(in) :: b !! second option
real,intent(in) :: c !! third option
!! do stuff
   write(*,*)a,b,c
end subroutine verbose
end module sample

I am not quite sure what behavior you want; but try just putting “! display: public protected” as the first line of your module file and that might be what you want.

I’m recycling this topic instead of opening a new one…

When documenting a generic procedure, FORD is documenting all the actual procedures, using their real and private names. Is there a way to use the generic name for all of them?

Other question: in a module I am defining and exporting long and descriptive names for some kinds, e.g. integer, parameter :: long_and_descriptive_name_of_the_kind, but internally I am using a shorter name for convenience e.g. integer, parameter :: mykind = long_and_descriptive_name. Of course, FORD is using the latter in the documentation when it appears in the interfaces. Is there a way to define aliases in the FORD command or config?

1 Like

Great questions @PierU. I use FORD to auto-document a moderately-sized package. It’s the best option I could find but I’m discouraged at how literal the documentation winds up being.

1 Like

I’m finalising FORD documentation for a project.
I cannot make links to work.
I get

Could not substitute link [[<component>]], '<component>' not found

Anyone could suggest what might be the cause?

EDIT: basically, I’m trying to cross-reference module procedures interfaces, like so:

module mod
[...]
interface
  module subroutine sub1()
     !! This references [[sub2]]
  end subroutine

  module subroutine sub2()
     !! This references [[sub1]]
  end subroutine
end interface
end module