Subject: [Fenics] Generation of docstring module

From: Johan Hake <[email-masked]>
Date: Thu, 2 Sep 2010 16:48:21 -0700

Hello!

I wonder how the docstring module is generated. More presisly the cpp.py file 
in that module. It looks very similare to what was generated by the 
generate_docstring.py which is still provided in DOLFIN. 

Is the goal to automate the generation of the the docstrings in this module, 
similare to what we have in C++? 

This is probably something you allready have discussed, but it has been 
difficult to keep track...

Johan

---

From: "Garth N. Wells" <[email-masked]>
Date: Fri, 03 Sep 2010 07:45:12 +0100

On 03/09/10 00:48, Johan Hake wrote:
> Hello!
>
> I wonder how the docstring module is generated. More presisly the cpp.py
> file in that module. It looks very similare to what was generated by the

I couldn't figure it either. It would be good to have some more comments 
in the code and some README files explaining what generates what.

Garth

> Is the goal to automate the generation of the the docstrings in this
> module, similare to what we have in C++?
>
> _______________________________________________
> Mailing list: https://launchpad.net/~fenics
> Post to     : [email-masked]
> Unsubscribe : https://launchpad.net/~fenics
> More help   : https://help.launchpad.net/ListHelp

---

From: Kristian Ølgaard <[email-masked]>
Date: Fri, 3 Sep 2010 10:20:16 +0200

>> generate_docstring.py which is still provided in DOLFIN.

The idea with the current setup is to write all docstrings in the
site-packages/dolfin/docstrings module by hand.
Ideally, we should generate it automatically since this will prevent
the docs for the Python interface to become out of sync with the C++
implementation. However, there are some problems with this approach.

1) The syntax in the C++ examples needs to be dealt with
2) Classes/functions are renamed/ignored (added?), we will need to
look in the *.i files to figure out what to do
3) Overloaded functions are handled using '*args', we need to extract these
4) Other problems that I'm unaware of

The current content (in docstrings/dolfin/cpp.py) is just a copy of
the old docstrings which was generated by 'generate_docstrings.py'
since we didn't have time to write proper docstrings for the entire
module. Only the Mesh class is currently documented and we need to add
proper documentation for the rest.

The generate_docstrings.py uses xml output from Doxygen to write the
docstrings.i, this is relatively slow, but once the docstrings module
is in place we can generate docstrings.i using this module which
should be fast. (Actually, we can already do this now since the module
is complete w.r.t. functions/classes).

Kristian

> I couldn't figure it either. It would be good to have some more comments in
> the code and some README files explaining what generates what.
>
> Garth
>
>

---

From: "Garth N. Wells" <[email-masked]>
Date: Fri, 03 Sep 2010 09:31:38 +0100

On 03/09/10 09:20, Kristian Ølgaard wrote:
> On 3 September 2010 08:45, Garth N. Wells<[email-masked]>  wrote:
>>
>>

Does this mean that I should be able to run 'generate_docstrings.py'? I 
get the error

Traceback (most recent call last):
   File "generate_docstrings.py", line 458, in <module>
     g.generate_interface_file_from_index()
   File "generate_docstrings.py", line 432, in 
generate_interface_file_from_index
     dfile = open(self._docstring_file,"w")
IOError: [Errno 2] No such file or directory: 
'/home/garth/code/fenics/dolfin.d/dolfin-all/dolfin/swig/swig/swig_docstrings.i'

when I run it.

Garth

---

From: Kristian Ølgaard <[email-masked]>
Date: Fri, 3 Sep 2010 10:52:05 +0200

On 3 September 2010 10:31, Garth N. Wells <[email-masked]> wrote:
> Does this mean that I should be able to run 'generate_docstrings.py'? I get
> the error

In the file generate.py at the bottom, you need to switch on the lines:

from generate_docstrings import DocstringGenerator

g = DocstringGenerator(header_files = docstring_headers,
swig_directory = ".", docstring_file_base = "")
g.generate_doxygen_documentation()
g.generate_interface_file_from_index()
g.clean()

and then comment the remainder of the lines which creates docstrings.i
from the docstrings module.

Then run 'python generate.py' to generate docstrings.i from xml files.

Kristian

>>> in

---

From: Johan Hake <[email-masked]>
Date: Fri, 3 Sep 2010 07:51:56 -0700

On Friday September 3 2010 01:31:38 Garth N. Wells wrote:
> >>> I wonder how the docstring module is generated. More presisly the
> >>> cpp.py file in that module. It looks very similare to what was
> >>> generated by the generate_docstring.py which is still provided in
> >>> DOLFIN.
> > 
> > 3) Overloaded functions are handled using '*args', we need to extract
> > these 4) Other problems that I'm unaware of
> > 

The error come because running the script from the konsole assume a predefined 
directory structure. By importing DocstringGenerator you can set these 
direcories, which we do in generate.py, as Kristian writes.

Johan

---

From: "Garth N. Wells" <[email-masked]>
Date: Fri, 03 Sep 2010 15:53:57 +0100

On 03/09/10 15:51, Johan Hake wrote:
> '/home/garth/code/fenics/dolfin.d/dolfin-all/dolfin/swig/swig/swig_docstrin
>
>  > gs.i'
>
>  >
>
>  >
>
>  > when I run it.
>
> The error come because running the script from the konsole assume a
> predefined directory structure. By importing DocstringGenerator you can
> set these direcories, which we do in generate.py, as Kristian writes.
>

This should all be in a README file somewhere, or commented in the code.

Garth

---

From: Johan Hake <[email-masked]>
Date: Fri, 3 Sep 2010 07:53:46 -0700

> site-packages/dolfin/docstrings module by hand.

Ok.

> 4) Other problems that I'm unaware of

Yes, these are all nasty one...
 
> is complete w.r.t. functions/classes).
Ok.

Johan

---

From: Harish Narayanan <[email-masked]>
Date: Fri, 03 Sep 2010 23:07:07 +0530

On 9/3/10 8:23 PM, Johan Hake wrote:
> cpp.py
> these

kmail's html e-mail with tiny fonts + poor eyesight = hard to read

Harish

---

From: Anders Logg <[email-masked]>
Date: Mon, 6 Sep 2010 11:53:03 +0200

> is complete w.r.t. functions/classes).

Do we have any functionality in place for handling documentation that
should be automatically generated from the C++ interface and
documentation that needs to be added later?

I assume that the documentation we write in the C++ header files (like
Mesh.h) will be the same that appears in Python using help(Mesh)?

But in some special cases, we may want to go in and handle
documentation for special cases where the Python documentation needs
to be different from the C++ documentation. So there should be two
different sources for the documentation: one that is generated
automatically from the C++ header files, and one that overwrites or
adds documentation for special cases. Is that the plan?

Another thing to discuss is the possibility of using Doxygen to
extract the documentation. We currently have our own script since (I
assume) Doxygen does not have a C++ --> reST converter. Is that
correct?

--
Anders

---

From: Kristian Ølgaard <[email-masked]>
Date: Mon, 6 Sep 2010 12:19:03 +0200

> documentation that needs to be added later?

No, not really.

> Mesh.h) will be the same that appears in Python using help(Mesh)?

Yes and no, the problem is that for instance overloaded methods will
only show the last docstring.
So, the Mesh.__init__.__doc__ will just contain the Mesh(std::str
file_name) docstring.

> adds documentation for special cases. Is that the plan?

The plan is currently to write the docstrings by hand for the entire
dolfin module. One of the reasons is that we rename/ignores
functions/classes in the *.i files, and if we we try to automate the
docstring generation I think we should make it fully automatic not
just part of it.
Also, we will need to change the syntax in all *example* code of the docstrings.
Maybe it can be done, but I'll need to give it some more careful
thought. We've already changed the approach a few times now, so I
really like the next try to close to our final implementation.

> assume) Doxygen does not have a C++ --> reST converter. Is that

I don't think Doxygen has any such converter, but there exist a
project http://github.com/michaeljones/breathe
which makes it possible to use xml output from Doxygen in much the
same way as we use autodoc for the Python module. I had a quick go at
it but didn't like the result. No links on the index pages to function
etc. So what we do now is better, but perhaps it would be a good idea
to use Doxygen to extract the docstrings for all classes and
functions, I tried parsing the xml output in the
test/verify_cpp_documentation.py script and it should be relatively
simple to get the docstrings since these are stored as attributes of
classes/functions.

Kristian

---

From: Anders Logg <[email-masked]>
Date: Mon, 6 Sep 2010 14:47:27 +0200

> > documentation that needs to be added later?

ok.

> So, the Mesh.__init__.__doc__ will just contain the Mesh(std::str

It would not be difficult to make the documentation extraction script
we have (in fenics-doc) generate the docstrings module and just
concatenate all constructor documentation. We are already doing the
parsing so spitting out class Foo: """ etc would be easy. Perhaps that
is an option.

> docstring generation I think we should make it fully automatic not

If we can make it 99% automatic and have an extra file with special
cases I think that would be ok.

> really like the next try to close to our final implementation.

I agree. :-)

> simple to get the docstrings since these are stored as attributes of

Perhaps an idea would be to use Doxygen for parsing and then have our
own script that works with the XML output from Doxygen?

  1. Use Doxygen to generate XML
  2. Generate docstrings/dolfin/cpp.py from XML
  3. Generate C++ reST from XML
  4. Generate Python reST from XML

--
Anders

---

From: Johan Hake <[email-masked]>
Date: Mon, 6 Sep 2010 08:08:10 -0700

> parsing so spitting out class Foo: """ etc would be easy. Perhaps that

There might be other overloaded methods too. We might try to setle on a format 
for these methods, or make this part of the 1% we need to handle our self.

> cases I think that would be ok.

Agree.
 
> > Also, we will need to change the syntax in all *example* code of the
> > docstrings. Maybe it can be done, but I'll need to give it some more
> > careful thought. We've already changed the approach a few times now, so
> > I really like the next try to close to our final implementation.
> 
> I agree. :-)
> 
> > test/verify_cpp_
> > ocumentation.py script and it should be relatively

I did not know we allready used Doxygen to extract information about class 
structure from the headers. What are the differences between using the XML 
from Doxygen to also extract the documentation, and the approach we use today?

Johan

---

From: Anders Logg <[email-masked]>
Date: Mon, 6 Sep 2010 17:13:44 +0200

> for these methods, or make this part of the 1% we need to handle our

ok. Should also be fairly easy to handle.

> structure from the headers.

I thought it was you who implemented the Doxygen documentation extraction?

> What are the differences between using the XML from Doxygen to also
> extract the documentation, and the approach we use today?

Pros (of using Doxygen):

  - Doxygen is developed by people that presumably are very good at
    extracting docs from C++ code

  - Doxygen might handle some corner cases we can't handle?

Cons (of using Doxygen):

  - Another dependency

  - We still need to write a script to parse the XML

  - The parsing of /// stuff from C++ code is very simple

--
Anders

---

From: Johan Hake <[email-masked]>
Date: Mon, 6 Sep 2010 08:24:21 -0700

On Monday September 6 2010 08:13:44 Anders Logg wrote:
> > > > > Do we have any functionality in place for handling documentation
> > > > > that should be automatically generated from the C++ interface and
> > > > > I assume that the documentation we write in the C++ header files
> > > > > (like Mesh.h) will be the same that appears in Python using
> > > > > help(Mesh)?
> > > > 
> > There might be other overloaded methods too. We might try to setle on a
> > format for these methods, or make this part of the 1% we need to handle
> > our self.
> 

Ok.

> > > > > documentation for special cases where the Python documentation
> > > > > needs to be different from the C++ documentation. So there should
> > > > > be two different sources for the documentation: one that is
> > > > > generated automatically from the C++ header files, and one that
> > > > > overwrites or adds documentation for special cases. Is that the
> > > > > plan?
> > > > 
> > > > careful thought. We've already changed the approach a few times now,
> > > > so I really like the next try to close to our final implementation.
> > > 
> > > I agree. :-)
> > > 
> > > > > extract the documentation. We currently have our own script since
> > > > > (I assume) Doxygen does not have a C++ --> reST converter. Is that
> > > > > correct?
> > > > 
> > > > it but didn't like the result. No links on the index pages to
> > > > function etc. So what we do now is better, but perhaps it would be a
> > > > good idea to use Doxygen to extract the docstrings for all classes
> > > > and functions, I tried parsing the xml output in the
> > > > test/verify_cpp_
> > I did not know we allready used Doxygen to extract information about
> > class structure from the headers.
> 

Duh... I mean that I did not know we used it in fenics_doc, in 
verify_cpp_documentation.py.

>   - Doxygen might handle some corner cases we can't handle?

Which we already have.

>   - We still need to write a script to parse the XML

We should be able to ust the xml parser in docstringgenerator.py.

>   - The parsing of /// stuff from C++ code is very simple

Yes, and this might be just fine. But if it grows we might consider using 
Doxygen. 

Would it be possible to setle on a format of the extracted documentation which 
we use as input to generate reST documentation. It would make it easier to do 
a switch to Doxygen XML whenever we figure this is needed, ie we just switch 
the backend of the documentation parser.

Johan

---

From: Kristian Ølgaard <[email-masked]>
Date: Mon, 6 Sep 2010 17:56:13 +0200

>> > > cases I think that would be ok.

Yes, but we'll need some automated testing to make sure that the 1%
does not go out of sync with the code.
Most likely the 1% can't be handled because it is relatively important
(definitions in *.i files etc.).

> verify_cpp_documentation.py.

We don't. I wrote this script to be able to test the documentation in
*.rst files against dolfin.
Basically, I parse all files and keep track of the classes/functions
which are defined in dolfin and try to match those up against the
definitions in the documentation (and vise versa) to catch
missing/obsolete documentation.

>>   - Doxygen might handle some corner cases we can't handle?

Definitely, and we don't have to maintain it.

> Yes, and this might be just fine. But if it grows we might consider using

But some cases are not handled correctly already (nested classes etc.)
so I vote for Doxygen.

> the backend of the documentation parser.

This will probably be a good idea, even if we start with Doxygen since
the xml output might change in format so we can easily adapt.

Kristian

---

From: Johan Hake <[email-masked]>
Date: Mon, 6 Sep 2010 13:14:40 -0700

On Monday September 6 2010 08:56:13 Kristian Ølgaard wrote:
> >> > > > > that should be automatically generated from the C++ interface
> >> > > > > and documentation that needs to be added later?
> >> > > > 
> >> > > > No, not really.
> >> > > 
> >> > > ok.
> >> > > 
> >> > > > Yes and no, the problem is that for instance overloaded methods
> >> > > > will only show the last docstring.
> >> > > It would not be difficult to make the documentation extraction
> >> > > script we have (in fenics-doc) generate the docstrings module and
> >> > > just concatenate all constructor documentation. We are already
> >> > > doing the parsing so spitting out class Foo: """ etc would be easy.
> >> > > Perhaps that is an option.
> >> > 
> >> > There might be other overloaded methods too. We might try to setle on
> >> > a format for these methods, or make this part of the 1% we need to
> >> > handle our self.
> >> 

If we choose to use Doxygen to extract the documentation, we need to figure 
out how to do this when we parse the XML information. 

The argument information is already handled by SWIG using:

  %feature("autodoc", "1");

This will generate signatures like:
  
        """
        __init__(self) -> Mesh
        __init__(self, Mesh mesh) -> Mesh
        __init__(self, string filename) -> Mesh

        Create mesh from data file. 
        """

The first part is ok, I think. But the comment relates to the latest parsed 
comment. We might deside to try to use the information in the xml file to 
generate all of this information. By this we can put in the relevant comments 
on the correct places like:

        """
        __init__(self) -> Mesh

        Create an empty mesh.

        __init__(self, Mesh mesh) -> Mesh

        Copy mesh.

        __init__(self, string filename) -> Mesh

        Create mesh from data file. 
        """

> >> > > > > needs to be different from the C++ documentation. So there
> >> > > > > should be two different sources for the documentation: one that
> >> > > > > is generated automatically from the C++ header files, and one
> >> > > > > that overwrites or adds documentation for special cases. Is
> >> > > > > that the plan?
> >> > > > 
> >> > > > The plan is currently to write the docstrings by hand for the
> >> > > > entire dolfin module. One of the reasons is that we
> >> > > > rename/ignores functions/classes in the *.i files, and if we we
> >> > > > try to automate the docstring generation I think we should make
> >> > > > it fully automatic not just part of it.
> >> > > 

Do we need to parse the different SWIG interface files? This sounds 
cumbersome. Couldn't we just automatically generate documentation from the 
parsed C++ header files. These are then used to generate the docstrings.i, 
which is used to put in documentation in cpp.py.

  * Ignored methods will be ignored, even if a 

      %feature("docstring") somemethod 
      "some docstring" 

    is generated for that method.

  * Extended methods needs to be handled in one of three ways:
    1) Write the docstring directly into the foo_post.i file
    2) Write a hook to an external docstring module for these methods

If we choose 2) we might have something like:

  %extend GenericMatrix {
     %pythoncode%{
     def data(self):
         docstringmodule.cppextended.GenericMatrix.data.__doc__
     %}
  }

in the foo_post.i files.

We would then have two parts in the external docstringmodule:

  1) for the extended Python layer (VariationalForm aso)
  2) for the extended Python layer in the cpp.py

For the rest, and this will be the main part, we rely on parsed docstrings 
from the headers.

The python programmers reference will then be generated based on the actuall 
dolfin module using sphinx and autodoc.

> >> > > > Also, we will need to change the syntax in all *example* code of
> >> > > > the docstrings. Maybe it can be done, but I'll need to give it
> >> > > > some more careful thought. We've already changed the approach a
> >> > > > few times now, so I really like the next try to close to our
> >> > > > final implementation.
> >> > > 
> >> > > I agree. :-)
> >> > > 
> >> > > > > extract the documentation. We currently have our own script
> >> > > > > since (I assume) Doxygen does not have a C++ --> reST
> >> > > > > converter. Is that correct?
> >> > > > 
> >> > > > same way as we use autodoc for the Python module. I had a quick go
> >> > > > at it but didn't like the result. No links on the index pages to
> >> > > > function etc. So what we do now is better, but perhaps it would
> >> > > > be a good idea to use Doxygen to extract the docstrings for all
> >> > > > classes and functions, I tried parsing the xml output in the
> >> > > > test/verify_cpp_
> >> > > > simple to get the docstrings since these are stored as attributes
> >> > > > of classes/functions.
> >> > > 
> >> > > Perhaps an idea would be to use Doxygen for parsing and then have
> >> > > our own script that works with the XML output from Doxygen?
> >> > 

Ok, so you do not use this to extact documentation?

Ok.

My itch with Doxygen is its specific syntax which make the header files look 
ugly. But I guess we write all our comments in reST, and then just use Doxygen 
to extract these. Should this information be used to generate both the 
docstring.i file and the c++ programmers reference?

I found a potential show breaker with Doxygen. It does not preserve line 
breakes... We need to put all the comments in the header files, which we will 
need to preserve, into a \verbatim \endverbatime block. This can probably be 
done where we need them. A good example is the table command in Mesh.h

> > Would it be possible to setle on a format of the extracted documentation
> > which we use as input to generate reST documentation. It would make it
> > easier to do a switch to Doxygen XML whenever we figure this is needed,
> > ie we just switch the backend of the documentation parser.
> 

Ok

Johan

---

From: Kristian Ølgaard <[email-masked]>
Date: Tue, 7 Sep 2010 00:59:47 +0200

>        Create mesh from data file.

I'd say that we should strive to make the docstring look like the one
for Mesh in docstrings/dolfin/cpp.py.
The argument information should contain links like :py:class:`Foo` if
functions/classes are used.
We can do this by storing the function docstrings, check for
overloaded functions and concatenate them if needed.

>    is generated for that method.

Yes, but what about renamed functions/classes??? This is what really bugs me.

>    2) Write a hook to an external docstring module for these methods

The beauty of extended methods is that we can assign to their docs
dynamically on import (unless we add a class, do we?), I do this
already. So no need to handle this case. All our problems arise from
what Swig does at the end of a class:

Mesh.num_vertices = new_instancemethod(_cpp.Mesh_num_vertices,None,Mesh)

which makes it impossible to assign to __doc__ --> we need to tell
Swig what docstrings do use.

>  1) for the extended Python layer (VariationalForm aso)

Since we're already aiming at generating the docstrings module
(dolfin/site-packages/dolfin/docstrings), maybe we should just extract
the docs from the extended Python layer in dolfin/site-packages/dolfin
and dump them in the docstrings? Then programmer's writing the Python
layer just need to document while they're coding, where they are
coding just like they do (or should anyways) for the C++ part.

> dolfin module using sphinx and autodoc.

We could/should probably use either the dolfin module or the generated
docstring module to generate the relevant reST files. Although we
might need to run some cross-checks with the Doxygen xml to get the
correct file names where the classes are defined in DOLFIN such that
we retain the original DOLFIN source tree structure. Otherwise all our
documentation will end up in cpp.rst which I would hate to navigate
through as a user.
I vote for using the generated docstrings module for the documentation
since it should contain all classes even if some HAS_* was not
switched on, which brings me to the last question, how do we handle
the case where some ifdefs result in classes not being generated in
cpp.py? They should still be documented of course.

Another issue we need to handle is any example code in the C++ docs
which must be translated into Python syntax. Either automatically, or
by some looking up in a dictionary, but that brings us right back to
something < 100% automatic.

> Ok, so you do not use this to extact documentation?

No, but I already visit all the class/function nodes so it should just
be a question of requesting the docstring attribute.

> docstring.i file and the c++ programmers reference?

Yes, no Doxygen markup crap here. The docstrings defined by '///'
should already be in reST and
we currently use this for the C++ programmer's reference.

> breakes...We need to put all the comments in the header files, which we will

Bummer. The line breaks are essential, not just for the table command
but for all the definition lists too i.e., the entire reST
documentation (both C++ and Python). No line breaks would also make
any output from calls like:

>>> help(dolfin.Mesh)

useless. There's no line break markup we can actually learn to live
with? But of course we would have to remove this later such that it
doesn't look completely stupid in the Python documentation.

Kristian

---

From: Johan Hake <[email-masked]>
Date: Mon, 6 Sep 2010 22:09:09 -0700

On Monday September 6 2010 15:59:47 Kristian Ølgaard wrote:
> >> >> > > > > Do we have any functionality in place for handling
> >> >> > > > > documentation that should be automatically generated from
> >> >> > > > > the C++ interface and documentation that needs to be added
> >> >> > > > > later?
> >> >> > > > 
> >> >> > > > No, not really.
> >> >> > > 
> >> >> > > ok.
> >> >> > > 
> >> >> > > > > I assume that the documentation we write in the C++ header
> >> >> > > > > files (like Mesh.h) will be the same that appears in Python
> >> >> > > > > using help(Mesh)?
> >> >> > > > 
> >> >> > > > So, the Mesh.__init__.__doc__ will just contain the
> >> >> > > > Mesh(std::str file_name) docstring.
> >> >> > > 
> >> >> > > doing the parsing so spitting out class Foo: """ etc would be
> >> >> > > easy. Perhaps that is an option.
> >> >> > 
> >> >> > There might be other overloaded methods too. We might try to setle
> >> >> > on a format for these methods, or make this part of the 1% we need
> >> >> > to handle our self.
> >> >> 
> > If we choose to use Doxygen to extract the documentation, we need to
> > figure out how to do this when we parse the XML information.
> > 
> > The first part is ok, I think. But the comment relates to the latest
> > parsed comment. We might deside to try to use the information in the xml
> > file to generate all of this information. By this we can put in the
> > relevant comments on the correct places like:
> > 
> >        """
> >        __init__(self) -> Mesh
> > 
> >        Create an empty mesh.
> > 

It looks nice.

> overloaded functions and concatenate them if needed.

But how do we extract the different arguments? I suppose this is collected by 
Doxygen, and we just need to parse these and ouput them in a correct way?
 
> >> >> > > > > documentation for special cases where the Python
> >> >> > > > > documentation needs to be different from the C++
> >> >> > > > > documentation. So there should be two different sources for
> >> >> > > > > the documentation: one that is generated automatically from
> >> >> > > > > the C++ header files, and one that overwrites or adds
> >> >> > > > > documentation for special cases. Is that the plan?
> >> >> > > > 
> >> >> > > If we can make it 99% automatic and have an extra file with
> >> >> > > special cases I think that would be ok.
> >> >> > 
> >> >> > Agree.
> >> 
> > cumbersome. Couldn't we just automatically generate documentation from
> > the parsed C++ header files. These are then used to generate the
> > docstrings.i, which is used to put in documentation in cpp.py.
> > 

This is handled by SWIG. If somemethod is a correct C++ DOLFIN type which is 
renamed, then will "some docstring" be the docstring of the renamed method.
 
> dynamically on import (unless we add a class, do we?), 

Do not think so.

> I do this already. 

Ok

> So no need to handle this case. All our problems arise from

Why do we need to assign to these methods? They allready get their docstrings 
from the docstrings.i file. However if we want to get rid of the 
new_instancemethod assignment above, we can just remove the 

  -fastproxy

option from the SWIG call.

> and dump them in the docstrings? 

I am confused. Do you suggest that we just document the extended Python layer 
directly in the pyton module as it is today? Why should we then dumpt the 
docstrings in a seperate docstring module? So autodoc can have something to 
shew on? Couldn't autodoc just shew on the dolfin module directly?

> Then programmer's writing the Python

Still confused why we need a certain docstring module.

> > For the rest, and this will be the main part, we rely on parsed
> > docstrings from the headers.
> > 
> > The python programmers reference will then be generated based on the
> > actuall dolfin module using sphinx and autodoc.
> 

This one got to technical for me. Do you say that there is no way to split the 
documentation into smaller parts without relying on the c++ module/file 
strucutre?

> cpp.py? They should still be documented of course.

I think we are fine if the server that generate the documentation has all 
optional packages, so the online documentation is fully up to date.

> something < 100% automatic.

Would it be possible to have just pointers to demos instead of example code. I 
know it is common to have example code in Python docstrings but I do not think 
it is equally common to have this in C++ header files.

> >> >> > > > Also, we will need to change the syntax in all *example* code
> >> >> > > > of the docstrings. Maybe it can be done, but I'll need to give
> >> >> > > > it some more careful thought. We've already changed the
> >> >> > > > approach a few times now, so I really like the next try to
> >> >> > > > close to our final implementation.
> >> >> > > 
> >> >> > > I agree. :-)
> >> >> > > 
> >> >> > > > > Another thing to discuss is the possibility of using Doxygen
> >> >> > > > > to extract the documentation. We currently have our own
> >> >> > > > > script since (I assume) Doxygen does not have a C++ --> reST
> >> >> > > > which makes it possible to use xml output from Doxygen in much
> >> >> > > > the same way as we use autodoc for the Python module. I had a
> >> >> > > > quick go at it but didn't like the result. No links on the
> >> >> > > > index pages to function etc. So what we do now is better, but
> >> >> > > > perhaps it would be a good idea to use Doxygen to extract the
> >> >> > > > docstrings for all classes and functions, I tried parsing the
> >> >> > > > xml output in the test/verify_cpp_
> >> >> > > > simple to get the docstrings since these are stored as
> >> >> > > > attributes of classes/functions.
> >> >> > > 
> >> >> > I did not know we allready used Doxygen to extract information
> >> >> > about class structure from the headers.
> >> >> 

Ok.

> >> > Yes, and this might be just fine. But if it grows we might consider
> >> > using Doxygen.
> >> 
> > My itch with Doxygen is its specific syntax which make the header files
> > look ugly. But I guess we write all our comments in reST, and then just
> > use Doxygen to extract these. Should this information be used to
> > generate both the docstring.i file and the c++ programmers reference?
> 

Good!

> > breakes...We need to put all the comments in the header files, which we
> > will need to preserve, into a \verbatim \endverbatime block. This can
> > probably be done where we need them. A good example is the table command
> > in Mesh.h
> 
> with? 

I think the \verbatim \endverbatim is the least intrusive in the header files. 
This would then look like:

    <detaileddescription><para><verbatim>
      A _Mesh_ consists of a set of connected and numbered mesh entities.
      ....    
      
      .. tabularcolumns:: |c|c|c|
     
      +--------+-----------+-------------+
      | Entity | Dimension | Codimension |
      +========+===========+=============+
      | Vertex |  0        |             |
      +--------+-----------+-------------+
      | Edge   |  1        |             |
      +--------+-----------+-------------+
      ....

      </verbatim> </para> </detaileddescription>

After some fidling with the parser (which used textwrap to beautify the text 
NOT!) I managed to get out this:

%feature("docstring") dolfin::Mesh "

      A _Mesh_ consists of a set of connected and numbered mesh entities.
      ....

      .. tabularcolumns:: |c|c|c|
     
      +--------+-----------+-------------+
      | Entity | Dimension | Codimension |
      +========+===========+=============+
      | Vertex |  0        |             |
      +--------+-----------+-------------+
      | Edge   |  1        |             |
      +--------+-----------+-------------+
      ....

";

Which should serve us well.

> But of course we would have to remove this later such that it

Shouldn't be nessesary!

Johan
 
> Kristian
> 
> >> > Would it be possible to setle on a format of the extracted
> >> > documentation which we use as input to generate reST documentation.
> >> > It would make it easier to do a switch to Doxygen XML whenever we
> >> > figure this is needed, ie we just switch the backend of the
> >> > documentation parser.
> >>

---

From: Anders Logg <[email-masked]>
Date: Tue, 7 Sep 2010 11:04:17 +0200

> (definitions in *.i files etc.).

I imagine that "1%" will be the same as the "1%" that we have special
treatment for in the SWIG files anyway, so it makes sense those need
special treatment.

So the idea would be:

  1. Document the C++ code in the C++ header files
  2. Document the extra Python code in the Python files (?)
  3. Document the extra SWIG stuff in a special file

> Definitely, and we don't have to maintain it.

We would need to maintain the script that extracts data from the
Doxygen-generated XML files.

> But some cases are not handled correctly already (nested classes etc.)

Not that I'm insisting on not using Doxygen, but isn't it quite rare
that we use nested classes? I think we decided at some point that we
wanted to avoid it for some other reason. I don't remember which but
it might have been a SWIG problem.

--
Anders

---

From: "Garth N. Wells" <[email-masked]>
Date: Tue, 07 Sep 2010 10:07:51 +0100

On 07/09/10 10:04, Anders Logg wrote:
>> On 6 September 2010 17:24, Johan Hake<[email-masked]>  wrote:

Nested classes were a problem for SWIG. I believe that it's no longer 
the case.

Garth

---

From: Anders Logg <[email-masked]>
Date: Tue, 7 Sep 2010 11:12:08 +0200

>       .. tabularcolumns:: |c|c|c|

Are you saying we need stuff like

in the header files?

That doesn't look very nice. In that case I would cast a clear vote
for not using Doxygen. It's a mess if we have to mix reST and some
other markup language. The beauty of reST is that it looks good and
non-intrusive.

Btw, we are already using a mix since generate_cpp_doc.py adds the
extra functionality for _Mesh_ which links "Mesh" to the documentation
page for that class.

--
Anders

--
Anders

---

From: Kristian Ølgaard <[email-masked]>
Date: Tue, 7 Sep 2010 12:01:55 +0200

>> for Mesh in docstrings/dolfin/cpp.py.

Yes, I know. :)

> Doxygen, and we just need to parse these and ouput them in a correct way?

I don't think we need to parse the arguments and output them. We just
get the function name and if we have more than one set of arguments
i.e., a different signature we know that we have an overloaded method
and how to handle it.
The arguments should be described in the *Arguments* section of the
individual docstring with links to classes formatted like
_MeshEntity_, which we will substitute with :py:class:`MeshEntity` or
:cpp:class:`MeshEntity` depending on which interface we document.
Although I just realised that standard C++ stuff like double* which
end up as numpy.array etc. should probably be handled.
On a related note:
int some_func()
and
const int some_func() const
are different in C++, but in Python we don't have const right?
This will simplify the documentation a lot.

> renamed, then will "some docstring" be the docstring of the renamed method.

Cool, I wasn't aware of that. Maybe it won't be impossible after all.

>> >    1) Write the docstring directly into the foo_post.i file

I like this option, if this is where we have the code for a function,
then this is where the docstring should be as it increases the
probability of the docstring being up to date.

> new_instancemethod assignment above, we can just remove the

Some history.
Initially, we wanted to have all docstrings separated from the DOLFIN
code and collected in the fenics-doc module. The easiest way to get
the >>> help(dolfin) docstring correct is to assign to __doc__
dynamically.
If we could do this we wouldn't even need the docstrings.i file and
things would be simple.
However, we discovered that this was not possible, and because of that
we still need to generate the docstrings.i file.
Then, still assuming we wanted to separate docs from code and keeping
docstrings in fenics-doc, I thought it would be easier to generate the
docstrings.i file from the handwritten docstrings module in
fenics-doc.
Some methods don't get their docstrings from the docstrings.i file
though, so we still need to assign to __doc__ which is the easiest
thing to do.
Just recently we decided to extract the docstrings from the C++
implementation thus moving the docs back into DOLFIN. This makes the
docstrings module almost superfluous with the only practical usage is
to have documentation for the extended methods defined in the _post.i
files but if we put the docstrings directly in the _post.i files we no
longer need it.

> option from the SWIG call.

OK, good to know, but let's not do that.

> shew on? Couldn't autodoc just shew on the dolfin module directly?

I'm confused too. :) I guess my head has not been properly reset
between the changes in documentation strategies.
The Sphinx autodoc can only handle one dolfin module, so we need to
either import the 'real' one or the docstrings dolfin module.
If we can completely remove the need for the docstrings module, then
we should of course include the 'real' one.

> Still confused why we need a certain docstring module.

Maybe we don't.

> documentation into smaller parts without relying on the c++ module/file

But how would you split it? It makes sense to keep the classes Mesh
and MeshEntity in the mesh/ part of the documentation. Unfortunately,
Swig doesn't add info to the classes in the cpp.py module about where
they were originally defined. This is why we need to pair it with info
from the xml output.

> optional packages, so the online documentation is fully up to date.

Maybe, but I think I saw somewhere that depending on the ifdefs some
names would be different and we need the documentation to be complete
regardless of the users installation.

> it is equally common to have this in C++ header files.

Since when did we care about common in FEniCS? :) I think small
input/output examples are good even for C++, look at the Mesh class
for instance.

>      .. tabularcolumns:: |c|c|c|

OK, looks reasonable. So it might be possible to do this after all.

Kristian

---

From: Kristian Ølgaard <[email-masked]>
Date: Tue, 7 Sep 2010 12:20:09 +0200

> treatment for in the SWIG files anyway, so it makes sense those need

I think that we can automate that last 1% too.

>  3. Document the extra SWIG stuff in a special file

All Python docstrings should be located where the code is.
In the Python layer (like dolfin/fem.py), or in the extended methods
in the *.i files for the dolfin/cpp.py module.

We then need to figure out how to change the syntax/name correctly
such that std::vector, double* etc. are mapped to the correct Python
arguments/return values, and how to handle the *example* code.

> it might have been a SWIG problem.

Look at http://www.fenics.org/newdoc/programmers-reference/cpp/function/Function.html
as a user I would be confused by LocalScratch and GatherScratch.

The documentation here is also rather confusing, yes we can fix it,
but similar cases will arise in the future.

http://www.fenics.org/newdoc/programmers-reference/cpp/mesh/MeshPrimitive.html

Kristian

---

From: Anders Logg <[email-masked]>
Date: Tue, 7 Sep 2010 12:37:31 +0200

> as a user I would be confused by LocalScratch and GatherScratch.

Those can be easily fixed by letting the script stop parsing when it
finds "private:".

> http://www.fenics.org/newdoc/programmers-reference/cpp/mesh/MeshPrimitive.html

That looks strange because Andre has used an arbitrary mix of "//" and
"///" in his comments. Don't blame my script for that. :-)

--
Anders

---

From: Kristian Ølgaard <[email-masked]>
Date: Tue, 7 Sep 2010 14:56:47 +0200

> Those can be easily fixed by letting the script stop parsing when it

OK, and if we are sure that no other nested classes are present in
DOLFIN I guess things should be fine.

> "///" in his comments. Don't blame my script for that. :-)

Alright alright, I'll never question the almighty
generate_cpp_documentation.py script again. :)

In light of the above and the Doxygen line break issue, maybe it's
best to use your script as a first try?
We just need to break it up in parsing (intermediate representation),
modifying (C++ and Python syntax) and writing stages (dump in
respective folders in the documentation) and settle on the
intermediate representation such that we can easily switch to a
Doxygen parser in case we decide to.

Kristian

---

From: Anders Logg <[email-masked]>
Date: Tue, 7 Sep 2010 15:02:20 +0200

> generate_cpp_documentation.py script again. :)

Sounds good. ;-)

> Doxygen parser in case we decide to.

Sounds like a compiler to me. :-)

And since I anticipated your comment, it is already broken up into two
different stages:

  generate_documentation (should maybe be extract_documentation)
  write_documentation

The intermediate representation is a simple Python list with class
names, signatures, comments etc. I'm sure it can be improved and
simplified.

--
Anders

---

From: Kristian Ølgaard <[email-masked]>
Date: Tue, 7 Sep 2010 15:50:11 +0200

> Sounds like a compiler to me. :-)

Yup.

>  generate_documentation (should maybe be extract_documentation)

Nice.

> names, signatures, comments etc. I'm sure it can be improved and

We will most likely need to refine it w.r.t. information, but I don't
think that we can simplify it, most likely it will become a little
more complex.

BTW, shouldn't the extract_documentation() part be in DOLFIN since we
intend to use to generate the docstrings.i file?

Then write_cpp_documentation() and write_python_documentation() is
part of fenics-doc, but they'll import extract_documentation() from
DOLFIN. Otherwise we'll end up with redundant code.

Kristian

---

From: Anders Logg <[email-masked]>
Date: Tue, 7 Sep 2010 16:13:12 +0200

> DOLFIN. Otherwise we'll end up with redundant code.

Yes, that sounds like a good idea.

Perhaps we should have a module 'documentation' as part of DOLFIN:

  from dolfin import documentation

  doc = documentation.extract_documentation(DOLFIN_DIR=...)

The extract_documentation function would look for the DOLFIN_DIR
environment variable and if it is not set, it would need the argument
to be supplied.

If we make it a part of DOLFIN, I have a feeling it will be more
robust since it just needs to extract the documentation, while other
scripts are responsible for generating various kinds of output.

--
Anders

---

From: Kristian Ølgaard <[email-masked]>
Date: Tue, 7 Sep 2010 16:46:53 +0200

> environment variable and if it is not set, it would need the argument

Sounds OK to me, but can't we just use os.path.abspath(__file__) to
get the file name, and then use our knowledge of the relative
location. We still need the DOLFIN_DIR for the writee_*_documentation
scripts to work though.

> scripts are responsible for generating various kinds of output.

I agree.

Kristian

---

From: Anders Logg <[email-masked]>
Date: Tue, 7 Sep 2010 17:19:31 +0200

> location. We still need the DOLFIN_DIR for the writee_*_documentation

Yes, that sounds better.

--
Anders

--
Anders

---

From: Johan Hake <[email-masked]>
Date: Tue, 7 Sep 2010 08:31:05 -0700

[snip]

>   <detaileddescription><para><verbatim>

No just:

  /// \verbatim
  /// Some comment...
  /// \endverbatim

Ok.

Johan

---

From: Johan Hake <[email-masked]>
Date: Tue, 7 Sep 2010 08:29:45 -0700

[snip]

No just:

  /// \verbatim
  /// Some comment...
  /// \endverbatim

Ok.

Johan

---

From: Johan Hake <[email-masked]>
Date: Tue, 7 Sep 2010 08:59:32 -0700

[snip]

> > But how do we extract the different arguments? I suppose this is
> > collected by Doxygen, and we just need to parse these and output them in
> > a correct way?
> 

And I guess the almighty generate_cpp_documentation.py script are able to 
extract the argument information?

> :cpp:class:`MeshEntity` depending on which interface we document.

Ok, but we only want that once for each method in python, even if it is 
overloaded?

> Although I just realized that standard C++ stuff like double* which

Yes this part I am a little worried about... But maybe a god handwritten 
lookup table will do the trick? At least for 99% of the cases ;)

> This will simplify the documentation a lot.

Yes, we tend to %ignore all const versions of different methods.

[snap]

> probability of the docstring being up to date.

Ok, lets settle on this one. We also need to make sure that all %extended 
methods in the C++ layer gets a proper docstring. However I am not really sure 
how this can be done :P

[snup]

> > Why do we need to assign to these methods? They already get their
> > docstrings from the docstrings.i file. However if we want to get rid of
> > the new_instancemethod assignment above, we can just remove the
> 
> Some history.

Ok, then I do not see any reason for a separate docstring module, makes life a 
lite bit easier...

[snep] 

> > I am confused. Do you suggest that we just document the extended Python
> > layer directly in the python module as it is today? Why should we then
> > dumpt the docstrings in a separate docstring module? So autodoc can have
> > something to shew on? Couldn't autodoc just shew on the dolfin module
> > directly?
> 

Ok!

> >> > actual dolfin module using sphinx and autodoc.
> >> 
> > This one got to technical for me. Do you say that there is no way to
> > split the documentation into smaller parts without relying on the c++
> > module/file structure?
> 
> But how would you split it? 

I do not know. But then I do not know what the generation step can take as 
different inputs.

> It makes sense to keep the classes Mesh

Ok, but say we keep all documentation in one module. If you are able to pair 
the different classes or functions with a module name, or file name you are 
able to create documentation which is structured after this hierarchy?
 
> regardless of the users installation.

Yes, I think this is most relevant for the different la backends.

> > Would it be possible to have just pointers to demos instead of example
> > code. I know it is common to have example code in Python docstrings but
> > I do not think it is equally common to have this in C++ header files.
> 

Ok, but put it in another way. It does look quite funny with a Python example 
in the C++ header. But if we start putting these in their own lookup file we 
are back again to the separate file we just abandone. We could maybe add some 
more markup for c++ and Python examples directly in the header?

[snop] sorry ran out of vowels...
 
> OK, looks reasonable. So it might be possible to do this after all.

Well, I think we have to let the almight script have a go first ;)

Johan

---

From: Johan Hake <[email-masked]>
Date: Tue, 7 Sep 2010 09:02:20 -0700

On Tuesday September 7 2010 08:19:31 Anders Logg wrote:
> > >> >> >> >> >> > > > > documentation that should be automatically
> > >> >> >> >> >> > > > > generated from the C++ interface and
> > >> >> >> >> >> > > > > I assume that the documentation we write in the
> > >> >> >> >> >> > > > > C++ header files (like Mesh.h) will be the same
> > >> >> >> >> >> > > > > that appears in Python using help(Mesh)?
> > >> >> >> >> >> > > > 
> > >> >> >> >> >> > > > Yes and no, the problem is that for instance
> > >> >> >> >> >> > > > overloaded methods will only show the last
> > >> >> >> >> >> > > > docstring.
> > >> >> >> >> >> > > It would not be difficult to make the documentation
> > >> >> >> >> >> > > extraction script we have (in fenics-doc) generate
> > >> >> >> >> >> > > the docstrings module and just concatenate all
> > >> >> >> >> >> > > constructor documentation. We are already doing the
> > >> >> >> >> >> > > parsing so spitting out class Foo: """ etc would be
> > >> >> >> >> >> > There might be other overloaded methods too. We might
> > >> >> >> >> >> > try to setle on a format for these methods, or make
> > >> >> >> >> >> > this part of the 1% we need to handle our self.
> > >> >> >> >> >> 
> > >> >> >> >> >> > > > > But in some special cases, we may want to go in
> > >> >> >> >> >> > > > > and handle documentation for special cases where
> > >> >> >> >> >> > > > > the Python documentation needs to be different
> > >> >> >> >> >> > > > > from the C++ documentation. So there should be
> > >> >> >> >> >> > > > > two different sources for the documentation: one
> > >> >> >> >> >> > > > > that is generated automatically from the C++
> > >> >> >> >> >> > > > > header files, and one that overwrites or adds
> > >> >> >> >> >> > > > The plan is currently to write the docstrings by
> > >> >> >> >> >> > > > hand for the entire dolfin module. One of the
> > >> >> >> >> >> > > > reasons is that we rename/ignores functions/classes
> > >> >> >> >> >> > > > in the *.i files, and if we we try to automate the
> > >> >> >> >> >> > > > docstring generation I think we should make it
> > >> >> >> >> >> > > > fully automatic not just part of it.
> > >> >> >> >> >> > > 
> > >> >> >> >> >> > > If we can make it 99% automatic and have an extra file
> > >> >> >> >> >> > > with special cases I think that would be ok.
> > >> >> >> >> >> > 
> > >> >> >> >> >> > Agree.
> > >> >> >> >> 
> > >> >> >> >> Yes, but we'll need some automated testing to make sure that
> > >> >> >> >> the 1% does not go out of sync with the code.
> > >> >> >> >> Most likely the 1% can't be handled because it is relatively
> > >> >> >> >> important (definitions in *.i files etc.).
> > >> >> >> > 
> > >> >> >> > I imagine that "1%" will be the same as the "1%" that we have
> > >> >> >> > special treatment for in the SWIG files anyway, so it makes
> > >> >> >> > sense those need special treatment.
> > >> >> >> 
> > >> >> >> In the Python layer (like dolfin/fem.py), or in the extended
> > >> >> >> methods in the *.i files for the dolfin/cpp.py module.
> > >> >> >> 
> > >> >> >> We then need to figure out how to change the syntax/name
> > >> >> >> correctly such that std::vector, double* etc. are mapped to the
> > >> >> >> correct Python arguments/return values, and how to handle the
> > >> >> >> *example* code.
> > >> >> >> 
> > >> >> >> >> >> > > > Also, we will need to change the syntax in all
> > >> >> >> >> >> > > > *example* code of the docstrings. Maybe it can be
> > >> >> >> >> >> > > > done, but I'll need to give it some more careful
> > >> >> >> >> >> > > > thought. We've already changed the approach a few
> > >> >> >> >> >> > > > times now, so I really like the next try to close
> > >> >> >> >> >> > > > to our final implementation.
> > >> >> >> >> >> > > 
> > >> >> >> >> >> > > I agree. :-)
> > >> >> >> >> >> > > 
> > >> >> >> >> >> > > > > Another thing to discuss is the possibility of
> > >> >> >> >> >> > > > > using Doxygen to extract the documentation. We
> > >> >> >> >> >> > > > > currently have our own script since (I assume)
> > >> >> >> >> >> > > > > Doxygen does not have a C++ --> reST converter.
> > >> >> >> >> >> > > > > Is that correct?
> > >> >> >> >> >> > > > 
> > >> >> >> >> >> > > > I don't think Doxygen has any such converter, but
> > >> >> >> >> >> > > > there exist a project
> > >> >> >> >> >> > > > http://github.com/michaeljones/breathe which makes
> > >> >> >> >> >> > > > it possible to use xml output from Doxygen in much
> > >> >> >> >> >> > > > the same way as we use autodoc for the Python
> > >> >> >> >> >> > > > module. I had a quick go at it but didn't like the
> > >> >> >> >> >> > > > result. No links on the index pages to function
> > >> >> >> >> >> > > > etc. So what we do now is better, but perhaps it
> > >> >> >> >> >> > > > would be a good idea to use Doxygen to extract the
> > >> >> >> >> >> > > > docstrings for all classes and functions, I tried
> > >> >> >> >> >> > > > parsing the xml output in the test/verify_cpp_
> > >> >> >> >> >> > > > simple to get the docstrings since these are stored
> > >> >> >> >> >> > > > as attributes of classes/functions.
> > >> >> >> >> >> > > 
> > >> >> >> >> >> > > Perhaps an idea would be to use Doxygen for parsing
> > >> >> >> >> >> > > and then have our own script that works with the XML
> > >> >> >> >> >> > > output from Doxygen?
> > >> >> >> >> >> > 
> > >> >> >> >> >> > I did not know we allready used Doxygen to extract
> > >> >> >> >> >> > information about class structure from the headers.
> > >> >> >> >> >> 
> > >> >> >> >> > Duh... I mean that I did not know we used it in fenics_doc,
> > >> >> >> >> > in verify_cpp_documentation.py.
> > >> >> >> >> 
> > >> >> >> >> We don't. I wrote this script to be able to test the
> > >> >> >> >> documentation in *.rst files against dolfin.
> > >> >> >> >> Basically, I parse all files and keep track of the
> > >> >> >> >> classes/functions which are defined in dolfin and try to
> > >> >> >> >> match those up against the definitions in the documentation
> > >> >> >> >> (and vise versa) to catch missing/obsolete documentation.
> > >> >> >> >> 
> > >> >> >> >> >> > What are the differences between using the XML from
> > >> >> >> >> >> > Doxygen to also extract the documentation, and the
> > >> >> >> >> >> > approach we use today?
> > >> >> >> >> >> 
> > >> >> >> >> >> Pros (of using Doxygen):
> > >> >> >> >> >> 
> > >> >> >> >> >>   - Doxygen is developed by people that presumably are
> > >> >> >> >> >> very good at extracting docs from C++ code
> > >> >> >> >> >> 
> > >> >> >> > We would need to maintain the script that extracts data from
> > >> >> >> > the Doxygen-generated XML files.
> > >> >> >> > 
> > >> >> >> >> >> Cons (of using Doxygen):
> > >> >> >> >> >> 
> > >> >> >> >> >>   - Another dependency
> > >> >> >> >> > 
> > >> >> >> >> > Which we already have.
> > >> >> >> >> > 
> > >> >> >> >> > Yes, and this might be just fine. But if it grows we might
> > >> >> >> >> > consider using Doxygen.
> > >> >> >> >> 
> > >> >> >> >> But some cases are not handled correctly already (nested
> > >> >> >> >> classes etc.) so I vote for Doxygen.
> > >> >> >> > 
> > >> >> >> > Not that I'm insisting on not using Doxygen, but isn't it
> > >> >> >> > quite rare that we use nested classes? I think we decided at
> > >> >> >> > some point that we wanted to avoid it for some other reason.
> > >> >> >> > I don't remember which but it might have been a SWIG problem.
> > >> >> >> 
> > >> >> >> Look at
> > >> >> >> http://www.fenics.org/newdoc/programmers-reference/cpp/function
> > >> >> >> /Function.html as a user I would be confused by LocalScratch and
> > >> >> >> GatherScratch.
> > >> >> > 
> > >> >> > Those can be easily fixed by letting the script stop parsing when
> > >> >> > it finds "private:".
> > >> >> 
> > >> >> >> The documentation here is also rather confusing, yes we can fix
> > >> >> >> it, but similar cases will arise in the future.
> > >> >> >> 
> > >> >> > That looks strange because Andre has used an arbitrary mix of
> > >> >> > "//" and "///" in his comments. Don't blame my script for that.
> > >> >> > :-)
> > >> >> 
> > >> >> We just need to break it up in parsing (intermediate
> > >> >> representation), modifying (C++ and Python syntax) and writing
> > >> >> stages (dump in respective folders in the documentation) and
> > >> >> settle on the intermediate representation such that we can easily
> > >> >> switch to a Doxygen parser in case we decide to.
> > >> > 
> > >> > And since I anticipated your comment, it is already broken up into
> > >> > two different stages:
> > >> > 

I vote to put it in dolfin_utils.

Johan

---

From: Anders Logg <[email-masked]>
Date: Tue, 7 Sep 2010 18:22:03 +0200

> extract the argument information?

It is a very simple script that just reads the header files line by
line, interprets lines starting with "///" as comments and the
following line(s) as a function signature (or class) until it finds
"{" or ";".

Getting the arguments would just be

  [arg.strip() for arg in signature.split("(")[1].split(")")[0].split(",")]

My point is that writing the documentation extraction script is not
exactly rocket science.

(Someone more well-versed than me in regexp can probably make some
improvements but 'split' goes a long way.)

> lookup table will do the trick? At least for 99% of the cases ;)

I think so too.

--
Anders

--
Anders

---

From: Kristian Ølgaard <[email-masked]>
Date: Tue, 7 Sep 2010 18:24:40 +0200

> extract the argument information?

No, but we should be able to figure this out from the signature (split
',' in '()').

> Ok, but we only want that once for each method in python, even if it is

No, I think we need to document the argument list for every overloaded
version like it is done in docstrings.dolfin.cpp.Mesh.

> lookup table will do the trick? At least for 99% of the cases ;)

I share your concern, but if, as you suggest, we'll be able to get God
to hand write our documentation I think we should be OK. :)
(a lookup table would be my best bet at the moment)

> methods in the C++ layer gets a proper docstring. However I am not really sure

I'm not sure I follow this, which %extended methods do you mean?

Agree.

> I do not know. But then I do not know what the generation step can take as

The write_python_documentation step should probably take the dolfin
module and the intermediate representation.

> able to create documentation which is structured after this hierarchy?

We need to figure out something, having everything in the cpp.py
module would create one big mess and it makes sense to follow the
DOLFIN C++ structure even for the Python interface.

> Yes, I think this is most relevant for the different la backends.

I think this is where I saw it, I had a quick look again but couldn't find it.

> in the C++ header.

The Python examples which are currently in the Mesh.h file are only
there because I wrote the docstring for the Python Mesh class first,
copy pasted and didn't have time to change the syntax. :)
We should have C++ syntax examples only in the *.h files of course.

But if we start putting these in their own lookup file we
> more markup for c++ and Python examples directly in the header?

Yes, or if the examples are really simple we can translate them
automatically. I don't know which is the best solution.

> Well, I think we have to let the almight script have a go first ;)

Agree. :)

Kristian

---

From: Johan Hake <[email-masked]>
Date: Tue, 7 Sep 2010 09:51:16 -0700

On Tuesday September 7 2010 09:24:40 Kristian Ølgaard wrote:
> >> > collected by Doxygen, and we just need to parse these and output them
> >> > in a correct way?
> >> 

Ok! Anders mentioned this too.
 
> version like it is done in docstrings.dolfin.cpp.Mesh.

Agree, I think I misunderstood you.

> to hand write our documentation I think we should be OK. :)

Good to have God on our side!

Ok!

> > methods in the C++ layer gets a proper docstring. However I am not really
> > sure how this can be done :P
> 

There are two ways to extend a class. 

  1) The C++ layer
  2) The Python layer

often we use 1) to create a protected helper method which is called using an 
extended method in the Python layer, 2). The latter can be properly documented 
directly. 

But some cases excists where we just extend the C++ layer, see for example the  
IMPLEMENT_VARIABLE_INTERFACE macro in shared_ptr_classes.i. These methods gets 
no docstrings and I am not sure it is possible to add them later.

> >> > docstrings from the docstrings.i file. However if we want to get rid
> >> > of the new_instancemethod assignment above, we can just remove the
> >> 
> >> Some history.
> > Ok, then I do not see any reason for a separate docstring module, makes
> > life a lite bit easier...
> 
> Agree.

Ok.

> > [snep]
> > 
> >> > I am confused. Do you suggest that we just document the extended
> >> > Python layer directly in the python module as it is today? Why should
> >> > we then dumpt the docstrings in a separate docstring module? So
> >> > autodoc can have something to shew on? Couldn't autodoc just shew on
> >> > the dolfin module directly?
> >> 
> >> >> > The python programmers reference will then be generated based on
> >> >> > the actual dolfin module using sphinx and autodoc.
> >> >> 
> >> >> We could/should probably use either the dolfin module or the
> >> >> generated docstring module to generate the relevant reST files.
> >> >> Although we might need to run some cross-checks with the Doxygen xml
> >> >> to get the correct file names where the classes are defined in
> >> >> DOLFIN such that we retain the original DOLFIN source tree
> >> >> structure. Otherwise all our documentation will end up in cpp.rst
> >> >> which I would hate to navigate through as a user.
> >> > 
> > I do not know. But then I do not know what the generation step can take
> > as different inputs.
> 

What is the intermediate representation?
 
> > Ok, but say we keep all documentation in one module. If you are able to
> > pair the different classes or functions with a module name, or file name
> > you are able to create documentation which is structured after this
> > hierarchy?
> 

Ok, but we do not have everything in a big cpp file. Types get imported into 
the Dolfin namespace in __init__ mostly from cpp.py. 

Would it help to add the cpp imports to submodules instead of the main 
__init__ file? We already have the submodules:

  mesh, common, compilemodules, fem, adaptivity and function

We could add:
  
  io, log, nls, ode, parameter, ale

and drag in stuff from cpp.py in these modules instead. In this way we 
structure the main __init__ file better, and you might be able to structure 
the pythons reference manual better?

> >> >> I vote for using the generated docstrings module for the
> >> >> documentation since it should contain all classes even if some HAS_*
> >> >> was not switched on, which brings me to the last question, how do we
> >> >> handle the case where some ifdefs result in classes not being
> >> >> generated in cpp.py? They should still be documented of course.
> >> > 
> >> > I think we are fine if the server that generate the documentation has
> >> > all optional packages, so the online documentation is fully up to
> >> > date.
> >> 

Ok.

> >> > code. I know it is common to have example code in Python docstrings
> >> > but I do not think it is equally common to have this in C++ header
> >> > files.
> >> 
> > Ok, but put it in another way. It does look quite funny with a Python
> > example in the C++ header.
> 

Ok.

> > are back again to the separate file we just abandone. We could maybe add
> > some more markup for c++ and Python examples directly in the header?
> 
> automatically. 

Maybe...

> I don't know which is the best solution.

Me neither.

> > Well, I think we have to let the almight script have a go first ;)

Cool!

Johan

---

From: Kristian Ølgaard <[email-masked]>
Date: Tue, 7 Sep 2010 19:08:34 +0200

> no docstrings and I am not sure it is possible to add them later.

OK, docstrings for 2) should go in the code as we agreed, and I guess
1) will fall under the 1% category which we may/may not be able to
handle in a clever way later.

> What is the intermediate representation?

It is whatever output we get from the extract_documentation script
which we'll add to the dolfin module. How it will look depends a bit
on what we need in the write_cpp_documentation and
write_python_documentation functions in fenics-doc.

> the Dolfin namespace in __init__ mostly from cpp.py.

My point is, there's no telling where the cpp.Mesh class was
originally defined. Everything from la to mesh to fem is dumped in the
cpp.py module.

> the pythons reference manual better?

I'm quite sure I tried something like this, and the problem was that
even if you do:

from dolfin.cpp import Mesh

in dolfin/mesh/__init__.py

the Mesh class will still point to dolfin.cpp when you inspect it -->
difficult to create the proper structure for the *.rst files.

I'll need to double check though that this is really the case.
And even if we can use the approach you outline above it means that we
have more stuff we need to manually maintain.

Kristian

---

From: Johan Hake <[email-masked]>
Date: Tue, 7 Sep 2010 10:19:15 -0700

On Tuesday September 7 2010 10:08:34 Kristian Ølgaard wrote:
> >> >> > collected by Doxygen, and we just need to parse these and output
> >> >> > them in a correct way?
> >> >> 
> >> > And I guess the almighty generate_cpp_documentation.py script are able
> >> > to extract the argument information?
> >> 
> >> > Ok, but we only want that once for each method in python, even if it
> >> > is overloaded?
> >> 
> >> > Yes this part I am a little worried about... But maybe a god
> >> > handwritten lookup table will do the trick? At least for 99% of the
> >> > cases ;)
> >> 
> >> > Ok, lets settle on this one. We also need to make sure that all
> >> > %extended methods in the C++ layer gets a proper docstring. However I
> >> > am not really sure how this can be done :P
> >> 
> > often we use 1) to create a protected helper method which is called using
> > an extended method in the Python layer, 2). The latter can be properly
> > documented directly.
> > 
> > But some cases excists where we just extend the C++ layer, see for
> > example the IMPLEMENT_VARIABLE_INTERFACE macro in shared_ptr_classes.i.
> > These methods gets no docstrings and I am not sure it is possible to add
> > them later.
> 

Ok.

> >> >> > docstrings from the docstrings.i file. However if we want to get
> >> >> > rid of the new_instancemethod assignment above, we can just remove
> >> >> > the
> >> >> 
> >> >> Some history.
> >> >> However, we discovered that this was not possible, and because of
> >> >> that we still need to generate the docstrings.i file.
> >> >> docstrings in fenics-doc, I thought it would be easier to generate
> >> >> the docstrings.i file from the handwritten docstrings module in
> >> >> fenics-doc.
> >> >> files but if we put the docstrings directly in the _post.i files we
> >> >> no longer need it.
> >> > 
> >> > Ok, then I do not see any reason for a separate docstring module,
> >> > makes life a lite bit easier...
> >> 
> >> Agree.
> > 
> > Ok.
> > 
> >> > [snep]
> >> > 
> >> >> > Python layer directly in the python module as it is today? Why
> >> >> > should we then dumpt the docstrings in a separate docstring
> >> >> > module? So autodoc can have something to shew on? Couldn't autodoc
> >> >> > just shew on the dolfin module directly?
> >> >> 
> >> >> >> Although we might need to run some cross-checks with the Doxygen
> >> >> >> xml to get the correct file names where the classes are defined
> >> >> >> in DOLFIN such that we retain the original DOLFIN source tree
> >> >> > This one got to technical for me. Do you say that there is no way
> >> >> > to split the documentation into smaller parts without relying on
> >> >> > the c++ module/file structure?
> >> >> 
> >> > I do not know. But then I do not know what the generation step can
> >> > take as different inputs.
> >> 

Ok.

> >> >> they were originally defined. This is why we need to pair it with
> >> >> info from the xml output.
> >> > 
> >> > Ok, but say we keep all documentation in one module. If you are able
> >> > to pair the different classes or functions with a module name, or
> >> > file name you are able to create documentation which is structured
> >> > after this hierarchy?
> >> 
> > Ok, but we do not have everything in a big cpp file. Types get imported
> > into the Dolfin namespace in __init__ mostly from cpp.py.
> 

Ok, but don't you just need a way to associate the classes to different 
modules? I thought this was what you used the doxygen output to. If we instead 
use the module representation we should be able to do this association 
directly with just the dolfin tree as the assosiated types should reside in:

  dolfin.submodule.__dict__

> > structure the main __init__ file better, and you might be able to
> > structure the pythons reference manual better?
> 

Would something that I sceted above work?

> have more stuff we need to manually maintain.

Sure, but now everything is throwed into dolfin/__init__.py which is really a 
mess now. 

Johan

---

From: Anders Logg <[email-masked]>
Date: Tue, 7 Sep 2010 19:23:42 +0200

> Sure, but now everything is throwed into dolfin/__init__.py which is really a

This discussion is getting long and complex. I'm tempted to just let
the two of you sort it out between you and then ask for a 10-line
summary.

And then, of course, suggest a completely different solution. :-)

--
Anders

---

From: Kristian Ølgaard <[email-masked]>
Date: Tue, 7 Sep 2010 22:55:07 +0200

On 7 September 2010 19:19, Johan Hake <[email-masked]> wrote:
> modules? I thought this was what you used the doxygen output to.

Yes, this is the plan. I thought I could use doxygen to tell me that
the class Mesh is defined in dolfin/mesh/Mesh.h, and then associate
the dolfin.cpp.Mesh class with the dolfin/mesh directory to generate
prog-ref/python/mesh/Mesh.rst.
But come to think of it, the potential renaming will screw this up arrrrgh.

If we instead
>  dolfin.submodule.__dict__

This has some potential, we just need to be careful what the
submodules import. The big drawback as I see it is that if someone
adds a class to say dolfin/mesh/Foo.h, we'll need to manually import
it in dolfin/mesh/__init__.py.
In the long run, I think that the doxygen approach will yield the most
stable result, but we'll most likely have to look in the *.i files for
%rename.

> Sure, but now everything is throwed into dolfin/__init__.py which is really a

No disagreeing you there.

Kristian

---

From: Kristian Ølgaard <[email-masked]>
Date: Tue, 7 Sep 2010 23:05:07 +0200

> And then, of course, suggest a completely different solution. :-)

That's what we're afraid of. In fact this is the reason we're still
discussing, to avoid implementing something which you'll tell us to
redo :)

I think we're quite close to a converged solution were the last
details concerns the structure of the Python documentation i.e., how
to retrieve the original DOLFIN library structure from the cpp.py
module.

Just a crazy thought, is it possible to tell Swig to split the modules
for us? Such that we get
dolfin/mesh --> site-packages/dolfin/mesh.
This will also speed up the compilation of the Python module if more
than one process is used.

Kristian

---

From: Johan Hake <[email-masked]>
Date: Tue, 7 Sep 2010 14:07:16 -0700

[snip]

> prog-ref/python/mesh/Mesh.rst.

Ok, the module way to do it might just yield what module you are in. But you 
should be able to check wether an instance in the module dict is a class, if 
so generate a .rst file for it.

> But come to think of it, the potential renaming will screw this up arrrrgh.

Should not be a problem if you go for my approach ;)

> submodules import. 

Definately! 

We either define a __all__ variable or just fill the module with some:

  from cpp.py import Mesh, ...

and skip the __all__ variable.

> The big drawback as I see it is that if someone

Well, that is what we already do, but we add it to dolfin/__init__.py, which 
we agree is messy.

> stable result, but we'll most likely have to look in the *.i files for

I might disagree with you. However you know the rst generation much better 
than me, so you just do what you think is best, and cost less wrt maintanance.

Johan

---

From: Johan Hake <[email-masked]>
Date: Tue, 7 Sep 2010 14:14:55 -0700

On Tuesday September 7 2010 14:05:07 Kristian Ølgaard wrote:
> >> > >> >> > But how do we extract the different arguments? I suppose this
> >> > >> >> > is collected by Doxygen, and we just need to parse these and
> >> > >> >> > output them in a correct way?
> >> > >> >> 
> >> > >> >> I don't think we need to parse the arguments and output them. We
> >> > >> >> just get the function name and if we have more than one set of
> >> > >> >> arguments i.e., a different signature we know that we have an
> >> > >> >> overloaded method and how to handle it.
> >> > >> > 
> >> > >> > And I guess the almighty generate_cpp_documentation.py script are
> >> > >> > able to extract the argument information?
> >> > >> 
> >> > >> No, but we should be able to figure this out from the signature
> >> > >> (split ',' in '()').
> >> > > 
> >> > >> >> The arguments should be described in the *Arguments* section of
> >> > >> >> the individual docstring with links to classes formatted like
> >> > >> >> :cpp:class:`MeshEntity` depending on which interface we
> >> > >> >> :document.
> >> > >> > 
> >> > >> > Ok, but we only want that once for each method in python, even if
> >> > >> > it is overloaded?
> >> > >> 
> >> > >> No, I think we need to document the argument list for every
> >> > >> overloaded version like it is done in docstrings.dolfin.cpp.Mesh.
> >> > > 
> >> > >> >> Although I just realized that standard C++ stuff like double*
> >> > >> >> which end up as numpy.array etc. should probably be handled.
> >> > >> > 
> >> > >> > handwritten lookup table will do the trick? At least for 99% of
> >> > >> > the cases ;)
> >> > >> 
> >> > >> I share your concern, but if, as you suggest, we'll be able to get
> >> > >> God to hand write our documentation I think we should be OK. :)
> >> > > 
> >> > >> >> >> >  * Extended methods needs to be handled in one of three
> >> > >> >> >> > ways: 1) Write the docstring directly into the foo_post.i
> >> > >> >> >> > file
> >> > >> >> 
> >> > >> >> I like this option, if this is where we have the code for a
> >> > >> >> function, then this is where the docstring should be as it
> >> > >> >> increases the probability of the docstring being up to date.
> >> > >> > 
> >> > >> > %extended methods in the C++ layer gets a proper docstring.
> >> > >> > However I am not really sure how this can be done :P
> >> > >> 
> >> > > often we use 1) to create a protected helper method which is called
> >> > > using an extended method in the Python layer, 2). The latter can be
> >> > > properly documented directly.
> >> > > 
> >> > > example the IMPLEMENT_VARIABLE_INTERFACE macro in
> >> > > shared_ptr_classes.i. These methods gets no docstrings and I am not
> >> > > sure it is possible to add them later.
> >> > 
> >> > >> >> > Why do we need to assign to these methods? They already get
> >> > >> >> > their docstrings from the docstrings.i file. However if we
> >> > >> >> > want to get rid of the new_instancemethod assignment above,
> >> > >> >> > we can just remove the
> >> > >> >> 
> >> > >> >> Some history.
> >> > >> >> Initially, we wanted to have all docstrings separated from the
> >> > >> >> DOLFIN code and collected in the fenics-doc module. The easiest
> >> > >> >> way to get the >>> help(dolfin) docstring correct is to assign
> >> > >> >> to __doc__ dynamically.
> >> > >> >> If we could do this we wouldn't even need the docstrings.i file
> >> > >> >> and things would be simple.
> >> > >> >> However, we discovered that this was not possible, and because
> >> > >> >> of that we still need to generate the docstrings.i file.
> >> > >> >> Then, still assuming we wanted to separate docs from code and
> >> > >> >> keeping docstrings in fenics-doc, I thought it would be easier
> >> > >> >> to generate the docstrings.i file from the handwritten
> >> > >> >> docstrings module in fenics-doc.
> >> > >> >> Some methods don't get their docstrings from the docstrings.i
> >> > >> >> file though, so we still need to assign to __doc__ which is the
> >> > >> >> easiest thing to do.
> >> > >> >> implementation thus moving the docs back into DOLFIN. This makes
> >> > >> >> the docstrings module almost superfluous with the only
> >> > >> >> practical usage is to have documentation for the extended
> >> > >> >> methods defined in the _post.i files but if we put the
> >> > >> >> docstrings directly in the _post.i files we no longer need it.
> >> > >> > 
> >> > >> >> > I am confused. Do you suggest that we just document the
> >> > >> >> > extended Python layer directly in the python module as it is
> >> > >> >> > today? Why should we then dumpt the docstrings in a separate
> >> > >> >> > docstring module? So autodoc can have something to shew on?
> >> > >> >> > Couldn't autodoc just shew on the dolfin module directly?
> >> > >> >> 
> >> > >> >> The Sphinx autodoc can only handle one dolfin module, so we need
> >> > >> >> to either import the 'real' one or the docstrings dolfin
> >> > >> >> module. If we can completely remove the need for the docstrings
> >> > >> >> module, then we should of course include the 'real' one.
> >> > >> > 
> >> > >> > Ok!
> >> > >> > 
> >> > >> >> >> layer just need to document while they're coding, where they
> >> > >> >> >> are coding just like they do (or should anyways) for the C++
> >> > >> >> >> part.
> >> > >> >> > 
> >> > >> >> >> > For the rest, and this will be the main part, we rely on
> >> > >> >> >> > parsed docstrings from the headers.
> >> > >> >> >> > 
> >> > >> >> >> > The python programmers reference will then be generated
> >> > >> >> >> > based on the actual dolfin module using sphinx and
> >> > >> >> >> > autodoc.
> >> > >> >> >> 
> >> > >> >> >> generated docstring module to generate the relevant reST
> >> > >> >> >> files. Although we might need to run some cross-checks with
> >> > >> >> >> the Doxygen xml to get the correct file names where the
> >> > >> >> >> classes are defined in DOLFIN such that we retain the
> >> > >> >> >> original DOLFIN source tree structure. Otherwise all our
> >> > >> >> >> documentation will end up in cpp.rst which I would hate to
> >> > >> >> >> navigate through as a user.
> >> > >> >> > 
> >> > >> >> > This one got to technical for me. Do you say that there is no
> >> > >> >> > way to split the documentation into smaller parts without
> >> > >> >> > relying on the c++ module/file structure?
> >> > >> >> 
> >> > >> > I do not know. But then I do not know what the generation step
> >> > >> > can take as different inputs.
> >> > >> 
> >> > >> >> and MeshEntity in the mesh/ part of the documentation.
> >> > >> >> Unfortunately, Swig doesn't add info to the classes in the
> >> > >> >> cpp.py module about where they were originally defined. This is
> >> > >> >> why we need to pair it with info from the xml output.
> >> > >> > 
> >> > >> > Ok, but say we keep all documentation in one module. If you are
> >> > >> > able to pair the different classes or functions with a module
> >> > >> > name, or file name you are able to create documentation which is
> >> > >> > structured after this hierarchy?
> >> > >> 
> >> > > Ok, but we do not have everything in a big cpp file. Types get
> >> > > imported into the Dolfin namespace in __init__ mostly from cpp.py.
> >> > 
> >> modules? I thought this was what you used the doxygen output to. If we
> >> instead use the module representation we should be able to do this
> >> association directly with just the dolfin tree as the assosiated types
> >> should reside in:
> >> 
> >> > > Would it help to add the cpp imports to submodules instead of the
> >> > > main __init__ file? We already have the submodules:
> >> > > 
> >> > > and drag in stuff from cpp.py in these modules instead. In this way
> >> > > we structure the main __init__ file better, and you might be able
> >> > > to structure the pythons reference manual better?
> >> > 
> >> Sure, but now everything is throwed into dolfin/__init__.py which is
> >> really a mess now.
> >> 
> >> Johan
> > 

Argee

> for us? 

He, he, if we would have stuck to SCons this would have been an easy shift, 
but now, I am not so sure...

However, I have structured the SWIG interface files, with the foo_post.i and 
foo_pre.i files with this in mind! So it should be possible... But we need to 
sort out internal dependencies of such modules first, and that can turn out to 
be difficult, as there might be some circular dependencies. But if we do not 
modularize libdolfin it might be possible.

> Such that we get

But we eventually need to import everything in the dolfin namespace as we do 
today. 

Johan

---

From: Kristian Ølgaard <[email-masked]>
Date: Wed, 8 Sep 2010 00:10:08 +0200

> so generate a .rst file for it.

Certainly.

> Should not be a problem if you go for my approach ;)

I know. :)

> Well, that is what we already do, but we add it to dolfin/__init__.py, which

All this is doable and relatively easy to manage if you stay on top of
it, my concern is just that if a class is added to C++ DOLFIN its
Python counterpart will end up in cpp.py and if it is not imported in
any submodule (or dolfin/__init__.py itself) a user can still reach it
by: dolfin.cpp.Foo, but there will be no documentation generated in
the programmer's reference.

> than me, so you just do what you think is best, and cost less wrt maintanance.

There's nothing to it once we have the Python module, we just let
Sphinx autodoc handle it i.e., for any given class Bar in module foo
we dump the following in the file dolfin/foo/Bar.rst

.. currentmodule:: dolfin.foo

.. autoclass:: Bar
  :members:
  :+ other options:

Let's sleep on it and see what we can dream up.

Kristian

---

From: Johan Hake <[email-masked]>
Date: Tue, 7 Sep 2010 15:18:10 -0700

On Tuesday September 7 2010 15:10:08 Kristian Ølgaard wrote:
> >> >> originally defined. Everything from la to mesh to fem is dumped in
> >> >> the cpp.py module.
> >> > 
> >> > Ok, but don't you just need a way to associate the classes to
> >> > different modules? I thought this was what you used the doxygen
> >> > output to.
> >> 
> > Ok, the module way to do it might just yield what module you are in. But
> > you should be able to check wether an instance in the module dict is a
> > class, if so generate a .rst file for it.
> 
> Certainly.
> 
> > Well, that is what we already do, but we add it to dolfin/__init__.py,
> > which we agree is messy.
> 

I would be more concerned about Foo not ending up in the dolfin namespace than 
Foo not beeing documented.

> > I might disagree with you. However you know the rst generation much
> > better than me, so you just do what you think is best, and cost less wrt
> > maintanance.
> 

Do that, I wait some hours for that strategi tough ;)

Johan