Version française
Home     About     Download     Resources     Contact us    
Browse thread
Re: Ocamldoc and multiple packages
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Bertrand Jeannet <Bertrand.Jeannet@i...>
Subject: Re: Ocamldoc and multiple packages


> ------------------------------------------------------------------------
> 
> Subject:
> [Caml-list] Ocamldoc and multiple packages
> From:
> Alexey Rodriguez <mrchebas@gmail.com>
> Date:
> Fri, 11 Sep 2009 17:47:09 +0200
> To:
> OCaml List <caml-list@inria.fr>
> 
> To:
> OCaml List <caml-list@inria.fr>
> 
> 
> Dear list,
> 
> I am trying to build ocamldoc documentation for an ocaml project that
> contains multiple packages (collections of modules built using
> -for-pack and -pack). My current setup generates documentation for
> each package but it won't generate hyperlinks to modules in other
> packages (module not found errors). I tried using the -load and -dump
> commands to allow ocamldoc see the ocamldoc-results of the referred to
> package, but I still get problems. I suspect that the problem arises
> because ocamldoc does not have a -pack option, so it always sees
> modules in a flat way. So if you have package Pack1 with module A, and
> module B in Pack2 which refers to Pack1.A.t, ocamldoc cannot solve
> this reference because it does not know that module A is inside
> another module called Pack1.
> 
> The solutions I see right now seem to involve more effort than I am
> willing to spend. So, before I embark on a task that might take too
> long I would like to ask for tips on this. How do you perform ocamldoc
> generation for projects with multiple packages? Thanks!
> 
> Cheers,
> 
> Alexey
> 


I wrote very recently a small script that packs source modules into a 
big module, and takes care of ocamldoc convention, which is to interpret 
in each file the first (** *) comment as the title associated to the module.

I am very bad at sh and gawk script, so the result (given below) is not 
very elegant...

It would of course be better (and much more robust) to have a direct 
support in ocamldoc.

Bertrand

-----------

#/bin/sh

# command line (very primitive...)
if test $1 != "-o"; then
     echo "ocamlpack: usage: ocamlpack -o outputmodule -title <str> 
module1 module2 ..."
     exit -1
fi
shift
out=$1
shift
if test $1 != "-title"; then
     echo "ocamlpack: usage: ocamlpack -o outputmodule -title <str> 
module1 module2 ..."
     exit -1
fi
shift
outtitle=$1
shift

# prepare output
/bin/rm -f $out.ml $out.mli
echo "(** $outtitle *)">$out.ml
echo "(** $outtitle *)">$out.mli

# iterate on input module,
for i in $*; do
     name=$i
# 1.A Look for the first (** *) comment, and output it to out.ml
# (see ocamldoc convention)
     gawk -v name=$name '
BEGIN {
   start=1
   # isolate module name from path/modulename
   nb = split(name, dirname, "/")
   name = dirname[nb]
   if (RLENGTH>0)
     name = substr(name,RINDEX,length(name)-RINDEX)
   # Capitalize the module name
   hd = toupper(substr(name,1,1))
   tl = substr(name,2,length(name)-1)
}
# Look for the first (** *) comment, and output it
{
   if (start==1) {
     match($0, /\(\*\*([ ]+)([^*]*)([ ]+)\*\)/ )
     if (RLENGTH>0){
       start=0
       title=substr($0,RSTART+4,RLENGTH-7)
       print "\n(** {1 Module [",hd tl "]:",title "} *)\n"
       print "module",hd tl,"= struct"
     }
   }
}
END {
   if (start==1) {
     print "\n(** {1 Module [",hd tl "]} *)\n"
     print "module",hd tl,"= struct"
   }
}
'	$i.ml >>$out.ml
# 1.B Output the rest of name.ml to out.ml
	gawk -v name=$name '
{
   if (start==1) {
     match($0, /\(\*\*([ ]+)([^*]*)([ ]+)\*\)/ )
     if (RLENGTH>0)
       start=0
     else
       print $0
   }
   else
     print " ",$0
}
END { print "end\n" }
'	$i.ml >>$out.ml

# 2.A Look for the first (** *) comment, and output it to out.mli
     gawk -v name=$name '
BEGIN {
   start=1
   nb = split(name, dirname, "/")
   name = dirname[nb]
   if (RLENGTH>0)
     name = substr(name,RINDEX,length(name)-RINDEX)
   hd = toupper(substr(name,1,1))
   tl = substr(name,2,length(name)-1)
}
{
   if (start==1) {
     match($0, /\(\*\*([ ]+)([^*]*)([ ]+)\*\)/ )
     if (RLENGTH>0){
       start=0
       title=substr($0,RSTART+4,RLENGTH-7)
       print "\n(** {1 Module [",hd tl "]:",title "} *)\n"
       print "module",hd tl,": sig"
     }
   }
}
END {
   if (start==1) {
     print "\n(** {1 Module [",hd tl "]} *)\n"
     print "module",hd tl,": sig"
   }
}
'	$i.mli >>$out.mli
# 2.B Output the rest of name.mli to out.mli
	gawk -v name=$name '
{
   if (start==1) {
     match($0, /\(\*\*([ ]+)([^*]*)([ ]+)\*\)/ )
     if (RLENGTH>0)
       start=0
     else
       print $0
   }
   else
     print " ",$0
}
END { print "end\n" }
'	$i.mli >>$out.mli
done