Skip to content
This repository has been archived by the owner on May 2, 2020. It is now read-only.

Generate docs for exported methods (of submodules)? #36

Open
lendle opened this issue Mar 27, 2015 · 4 comments
Open

Generate docs for exported methods (of submodules)? #36

lendle opened this issue Mar 27, 2015 · 4 comments

Comments

@lendle
Copy link
Contributor

lendle commented Mar 27, 2015

First, thanks for Docile and Lexicon! I'm not sure if this issue belongs here or with Docile, or somewhere in the middle.

Suppose I have

module M

module A
using Docile
@document
"x is 0"
x=0
"y is 1"
y=1
end

module B
using Docile
@document 
"a is :a"
a = :a
"b is :b"
b = :b
end

import .A.x, .B.a
export x #but not a
end

What I would like is to generate documentation for M using save that includes docs for exported objects from submodule(s)†. I don't want to have to expose the user to all internal documentation of A and B in order to document the exported objects of M. Any thoughts on best practices here?

† or something like that at least. Maybe docs for exported objects of submods is not exactly right.

@MichaelHatherly
Copy link
Owner

(The line between Docile- and Lexicon-specific issues is a bit vague, so I'm not bothered by where they get filed.)

I've come across this issue as well, a few "solutions" I've tried:

  • Flatten the modules into a single one, which probably isn't what you'd want.
  • Document imported objects in module M.

The second option works for most cases apart from constants and macros:

module M

using Docile
@document

module A
using Docile
@document

x=0
"y is 1"
y=1
end

module B
using Docile
@document 
"a is :a"
a = :a
"b is :b"
b = :b
end

import .A.x, .B.a
export x #but not a

"x is 0"
:x

end

This ends up documenting the integer 0 in module M, not quite what you'd want. If x was a method then you could do:

"x is 0"
:x

to document the Function x or:

"x is 0"
(x,)

to document the Method x with zero arguments.


So Functions, Methods, (and Types) can be documented in different modules like this. Globals and macros don't support this. I may be able to coax Docile into allowing that.

Problems with this approach:

  • Docstrings are not local to the implementation.
  • Source links in generated docstrings will point to the "wrong" location.

@lendle
Copy link
Contributor Author

lendle commented Mar 27, 2015

(I'm really interested in documenting methods and types, not really integers as in my example above.)

How hard would it be to do something like this:

module M

using Docile
@document

module A
using Docile
@document

"f returns 0"
f(x)=0
"g returns 1"
g(x) = 1
end

import .A.f
export f

@get_doc(A.f) # <-----
(f, Any)

end

where @get_doc or a more appropriately named macro gets the docstring (& metadata) from A and associates it with f in M? That would keep the docstrings w/ the implementation. This might also be useful if there are multiple documented methods of A.f, but I only want to display the docs for some.

Relating to the last point and also to #37, what do you think about checking for an internal tag in the meta data to exclude from output generated by save?

Like

#...
@doc meta("returns 1 "; internal = true) ->
g(x) = 1
#...

@MichaelHatherly
Copy link
Owner

That could possibly work. Something like:

module M

using Docile
@document

module A
using Docile
@document

"f returns 0"
f(x)=0
"g returns 1"
g(x) = 1
end

import .A.f
export f

@get_doc(A.f, (f, Any))

end

where @get_doc (or something better named) would be a noop macro (kind of like @comment is) and just signal the parser to map docstrings from one module to another. Inner modules would need to have already had their docstrings captured for this to work, but it appears that this is already the case.

@get_doc(A.f, (f, Any)) would map the docstring associated with the Function A.f to the Method f(::Any) is this case. Not sure if only allowing mapping from T -> T (where T is a method, function, etc.) should be legal. Mapping from a Function to Method might become a headache.


You should be able to filter out internal-tagged docstrings already using the filter method.

module T

using Docile

@doc meta("return 1"; internal = true) ->
g(x) = 1

end

using Docile, Docile.Interface, Lexicon

filtered_metadata = filter(metadata(T)) do ent
     !metadata(ent)[:internal]
end

save("out.md", MIME"text/md"(), filtered_metadata)

(Writing that out I feel there's some room to improve the interface a little.)

@peter1000
Copy link
Contributor

i did not go through all of this but you may also want to have a look at the ne w Config implementation which allows some prefiltering. `https://github.com/MichaelHatherly/Lexicon.jl/blob/master/src/render.jl#L9

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants