From a4079c7e85145dce9cfc232f589033b7a11af68b Mon Sep 17 00:00:00 2001 From: timkittel <19408882+timkittel@users.noreply.github.com> Date: Wed, 5 Dec 2018 03:31:46 +0100 Subject: [PATCH] added filter function to @autodocs (#885) --- docs/src/man/syntax.md | 23 ++++++++++++++++++++- src/Expanders.jl | 33 ++++++++++++++++++++----------- test/examples/make.jl | 17 ++++++++++++++++ test/examples/src/lib/autodocs.md | 15 ++++++++++++++ test/examples/tests.jl | 2 +- 5 files changed, 77 insertions(+), 13 deletions(-) diff --git a/docs/src/man/syntax.md b/docs/src/man/syntax.md index e1f28fd28b..a86b81bbf4 100644 --- a/docs/src/man/syntax.md +++ b/docs/src/man/syntax.md @@ -85,6 +85,27 @@ docstrings. Note that page matching is done using the end of the provided string `a.jl` will be matched by *any* source file that ends in `a.jl`, i.e. `src/a.jl` or `src/foo/a.jl`. +To filter out certain docstrings by your own criteria, you can provide function with them +`Filter` keyword: + +````markdown +```@autodocs +Modules = [Foo] +Filter = t -> typeof(t) === DataType && t <: Foo.C +``` +```` + +In the given example, only the docstrings of the subtypes of `Foo.C` are shown. Instead +of an [anonymous function](https://docs.julialang.org/en/v1/manual/functions/index.html#man-anonymous-functions-1) +you can give the name of a function you defined beforehand, too: + +````markdown +```@autodocs +Modules = [Foo] +Filter = myCustomFilterFunction +``` +```` + To include only the exported names from the modules listed in `Modules` use `Private = false`. In a similar way `Public = false` can be used to only show the unexported names. By default both of these are set to `true` so that all names will be shown. @@ -109,7 +130,7 @@ Order = [:type] !!! note - When more complex sorting and filtering is needed then use `@docs` to define it + When more complex sorting is needed then use `@docs` to define it explicitly. ## `@ref` link diff --git a/src/Expanders.jl b/src/Expanders.jl index 618dde120f..a0c35ea3c3 100644 --- a/src/Expanders.jl +++ b/src/Expanders.jl @@ -332,7 +332,11 @@ function Selectors.runner(::Type{AutoDocsBlocks}, x, page, doc) for (ex, str) in Utilities.parseblock(x.code, doc, page) if Utilities.isassign(ex) try - fields[ex.args[1]] = Core.eval(curmod, ex.args[2]) + if ex.args[1] == :Filter + fields[ex.args[1]] = Core.eval(Main, ex.args[2]) + else + fields[ex.args[1]] = Core.eval(curmod, ex.args[2]) + end catch err push!(doc.internal.errors, :autodocs_block) @warn "failed to evaluate `$(strip(str))` in `@autodocs` block in $(Utilities.locrepr(page.source))" exception = err @@ -346,6 +350,7 @@ function Selectors.runner(::Type{AutoDocsBlocks}, x, page, doc) pages = map(normpath, get(fields, :Pages, [])) public = get(fields, :Public, true) private = get(fields, :Private, true) + filterfunc = get(fields, :Filter, x -> true) results = [] for mod in modules for (binding, multidoc) in Documenter.DocSystem.getmeta(mod) @@ -355,16 +360,22 @@ function Selectors.runner(::Type{AutoDocsBlocks}, x, page, doc) # What category does the binding belong to? category = Documenter.DocSystem.category(binding) if category in order && included - for (typesig, docstr) in multidoc.docs - path = normpath(docstr.data[:path]) - object = Utilities.Object(binding, typesig) - if isempty(pages) - push!(results, (mod, path, category, object, isexported, docstr)) - else - for p in pages - if endswith(path, p) - push!(results, (mod, p, category, object, isexported, docstr)) - break + # filter the elements after category/order has been evaluated + # to ensure that e.g. when `Order = [:type]` is given, the filter + # function really receives only types + filtered = Base.invokelatest(filterfunc, Core.eval(binding.mod, binding.var)) + if filtered + for (typesig, docstr) in multidoc.docs + path = normpath(docstr.data[:path]) + object = Utilities.Object(binding, typesig) + if isempty(pages) + push!(results, (mod, path, category, object, isexported, docstr)) + else + for p in pages + if endswith(path, p) + push!(results, (mod, p, category, object, isexported, docstr)) + break + end end end end diff --git a/test/examples/make.jl b/test/examples/make.jl index 12140618ff..5607179b84 100644 --- a/test/examples/make.jl +++ b/test/examples/make.jl @@ -77,6 +77,23 @@ module AutoDocs "Macro `B.@m`." macro m() end end + + module Filter + "abstract super type" + abstract type Major end + + "abstract sub type 1" + abstract type Minor1 <: Major end + + "abstract sub type 2" + abstract type Minor2 <: Major end + + "random constant" + qq = 3.14 + + "random function" + function qqq end + end end # Build example docs diff --git a/test/examples/src/lib/autodocs.md b/test/examples/src/lib/autodocs.md index 48149dd4f8..087c3305f1 100644 --- a/test/examples/src/lib/autodocs.md +++ b/test/examples/src/lib/autodocs.md @@ -50,3 +50,18 @@ Modules = [AutoDocs.Pages.E] Order = [:type] ``` +## Filtering + +Should include docs for + + * [`AutoDocs.Filter.Major`](@ref) + * [`AutoDocs.Filter.Minor1`](@ref) + * [`AutoDocs.Filter.Minor2`](@ref) + +in that order. + +```@autodocs +Modules = [AutoDocs.Filter] +Order = [:type] +Filter = t -> t <: AutoDocs.Filter.Major +``` diff --git a/test/examples/tests.jl b/test/examples/tests.jl index 446190b7cc..c1aaf1ebb5 100644 --- a/test/examples/tests.jl +++ b/test/examples/tests.jl @@ -72,7 +72,7 @@ end end end - @test length(doc.internal.objects) == 38 + @test length(doc.internal.objects) == 41 end @testset "HTML: local" begin