MichaelHatherly / Lexicon.jl

Julia package documentation generator.
Other
16 stars 18 forks source link

Clean up display of method signatures. #118

Closed peter1000 closed 9 years ago

peter1000 commented 9 years ago

This preceeds a couple of related issues:

MichaelHatherly commented 9 years ago

When a type has multiple constructors, is there a way to gather them all together with the type in the generated documentation instead of having them listed with the rest of the methods?

Yes, might be best to group constructors with their type and also methods with their function (as I've mentioned before).

peter1000 commented 9 years ago

maybe that should be an option because not everyone might want to mix types with there constructor methods: might get also a bit strange with the filtering. Anyway lets see how things go... won't have much time the next couple of days.

MichaelHatherly commented 9 years ago

maybe that should be an option because not everyone might want to mix types with there constructor methods

Yeah, we'll just have to try different options out and see what works nicely.

won't have much time the next couple of days

No rush, I'll mostly be working on the query code so hopefully won't get too much in the way of your current PR.

peter1000 commented 9 years ago

Do you know of an easy way to get the constructor for a type? Except matching the name: somthing like the functions. methods? I did not yet look into it just asking. And about other methods (which also do similar things) with other names like you use for

section(args...; kwargs...) = (Section, args, config(kwargs))
page(args...; kwargs...)    = (Page,    args, config(kwargs))
docs(args...; kwargs...)    = (Docs,    args, config(kwargs))
MichaelHatherly commented 9 years ago

Do you know of an easy way to get the constructor for a type? Except matching the name: somthing like the functions. methods? I did not yet look into it just asking.

Does

julia> type T x end

julia> methods(T)
# 1 method for generic function "T":
T(x)

in 0.3 and

julia> type T x end

julia> methods(T)
3-element Array{Any,1}:
 call(::Type{T}, x)                             
 call{T}(::Type{T}, arg) at essentials.jl:53    
 call{T}(::Type{T}, args...) at essentials.jl:54

in 0.4 do what you're needing?

And about other methods (which also do similar things) with other names like you use for

Not sure what you're asking here. Those are lowercase simply to make typing out a document tree slightly easier.

peter1000 commented 9 years ago

Method Groups.

"f_36"
(:f_36, Vararg)

f_36() = ()
f_36(x) = ()
f_36(x, y) = ()
f_36(x, y, z) = ()
peter1000 commented 9 years ago

Question: is that on purpose or needs to be corrected?

Method Groups.

"f_36"
(:f_36, Any, Any, Any)

f_36(x, y, z) = ()
f_36(x::Dict, y, z) = ()

generates 2 objects: line number: 154

Method f_36 (154,"Functions.jl") f_36(x::Dict{K,V}, y, z) at Functions.jl:158
Method f_36 (154,"Functions.jl") f_36(x, y, z) at Functions.jl:157

If one has an additional docstring that does not show up in the group?

"f_36"
(:f_36, Any, Any, Any)

f_36(x, y, z) = ()

"Some additional text"
f_36(x::Dict, y, z) = ()

generates ONLY 1 objects: line number: 154

Method f_36 (154,"Functions.jl") f_36(x, y, z) at Functions.jl:157
Method f_36 (159,"Functions.jl") f_36(x::Dict{K,V}, y, z) at Functions.jl:160
MichaelHatherly commented 9 years ago

did not find a documentation for this variation. here

Yeah, that example is misleading and needs to be changed. The signatures must match exactly for the tuple syntax.

If one has an additional docstring that does not show up in the group?

Only one docstring can be stored per Method. The second one ("Some additional text") overwrites the first ("f_36"). We could warn the user when that happens perhaps, I'd rather not disallow it completely though.

peter1000 commented 9 years ago

Yeah, that example is misleading and needs to be changed. The signatures must match exactly for the tuple syntax.

If we only change the example this is not true, isn't it?

If one has an additional docstring that does not show up in the group?

I'd rather not disallow it completely though.

No, but would it be possible to have a meta: with all obj belonging to a group.


Anyway I'm a bit stuck with the whole group / method / function definitions and type / constructor how to possible group them in the output.

The best I can think of is to group per docstring line number which should always produce just one output.

All othere cases seem to get mixed up if one uses filters: per categories or isexported etc...

I will start rebasing some of the code now and split it into separate PR

MichaelHatherly commented 9 years ago

If we only change the example this is not true, isn't it?

It's just using methods(::Function, ::Tuple) to determine which methods are applicable. See here. We can mention the behaviour mirrors that of a methods call.

Anyway I'm a bit stuck with the whole group / method / function definitions and type / constructor how to possible group them in the output.

I'll try have a look into this myself today.

peter1000 commented 9 years ago

I'll try have a look into this myself today

I thought like this: for each actual docstring to have one output. (based on the :textsource line)

User can anyway overwrite this but I thought as default:

methods: as you suggested use the name function as object definition line and below the actual methods as written in the source code.

Your example

"f_14"
f_14{T<:FloatingPoint}(f, a::T,b::T,c::T...;
                       abstol=zero(T),
                       reltol=sqrt(eps(T)),
                       maxevals=10^7,
                       order=7,
                       norm=vecnorm
                       ) = ()

f_14

f_14{T <: FloatingPoint}(f, a::T, b::T, c::T...; reltol=sqrt(eps(T)), maxevals=10 ^ 7, order=7, norm=vecnorm)

The actual getparsed content of the object .....


To save space and avoid extra spliting or extraction I would use the return of the expr args as they are and only add space between the commas.

For methods with defaults I would also only output the main method as written in the source code. Reason: if a method has many defaults listing all would maybe not be the best as well I belief it is has a reason the coder used such a method instead of multiple methods.

For all your special groups it would probably nice to list each one - but for this Docile needs to provide something.

Documentation authors can anyway use their own if they really need something else.

peter1000 commented 9 years ago

Doing it like that above would solve already most of this 3 issues

peter1000 commented 9 years ago

Issue:

For the default implementation I would just skip this or make it optional

peter1000 commented 9 years ago

Uploaded an example to: http://peter1000.github.io/new_lexicon_example_docs1/api/docile/

See also the long methods of your example: http://peter1000.github.io/new_lexicon_example_docs1/api/docile.examples/#f_14

MichaelHatherly commented 9 years ago

Yes, that output looks clearer. I'll post a some ideas I've had regarding this today a bit later.

MichaelHatherly commented 9 years ago

I think the modules should remain as part of the signature. Especially since we can combine several modules and change the sorting order.

Longer signatures should perhaps be split across lines like so:

Foo.Baz.baz{
    T <: Integer,
    S <: AbstractString,
}(
    x :: Array{T, 2},
    y,
    z :: S = ""
)
peter1000 commented 9 years ago

I think the modules should remain as part of the signature. Especially since we can combine several modules and change the sorting order.

Maybe this should be optional.

Reason most julia Pkg seem to be quite small and if one has a structure as the current Docile http://docilejl.readthedocs.org/en/latest/api/Docile.Cache/

I think it is a lot of repetition. if already the sidebar says: Docile.Cache, the header of the page says Docile.Cache and the url ends in api/Docile.Cache/ I don't think each method needs to also start with Docile.Cache.getmeta(m::Module).

Is that not the point in having named Sections and a page title.

Maybe for combined modules it makes sense to me. Anyway just a personal thought, I have read somewhere on the julia (can't find it now) list that some do prefer having the whole signature with everything in the output. (it was unrelated to Docile/Lexicon)

peter1000 commented 9 years ago
Foo.Baz.baz{
    T <: Integer,
    S <: AbstractString,
}(
    x :: Array{T, 2},
    y,
    z :: S = ""
)

Maybe it is worth to consider not adding all the additional spaces between and use the return of the :parameters as they are.

And only adding a space after the comma (or in your example a new line)

I did it here like that: https://github.com/MichaelHatherly/Lexicon.jl/pull/116/files#diff-01285fe4a25bbc4da684aa18148e934eR111

hayd commented 9 years ago

How's about this as an idea (I was doing with LightGraphs):

grab

(Then could do the other signatures that share an different docstring.)

In this way, docstrings can be shared and the source(s) can be linked to, whilst being less "in your face"/longwinded.

@MichaelHatherly and I were discussing this on another issue/commit (#126 and https://github.com/JuliaGraphs/LightGraphs.jl/commit/9bf32d4f4b9d61b5a5f0c4ef89fddd65fb8b8722) how to extract all the methods defined in your package which share a docstring).

MichaelHatherly commented 9 years ago

That looks really nice! So the source: 1 2 3 are each links to the source of their respective signatures?

peter1000 commented 9 years ago

In the new Docile (julia 0.4/0.5) not anymore relevant.