Open aviks opened 4 years ago
Yeah, this would be good to have in the manual somewhere. What I usually do is the following, if you have the standard setup with docs/Project.toml
:
$ julia --project=docs/
pkg> instantiate
pkg> dev .
julia> include("docs/make.jl")
You can even drop a using Revise
in there so that you wouldn't have to reload Julia when updating the docstrings.
What I usually do is the following
Yeah, that sounds reasonable. All of this is, of course, obvious in retrospect, but I've struggle with figuring this out, and seen other's do that.
This came up on Slack too; the Documenter docs are making people run julia make.jl
all the time.
It would be nice to write a guide targeted for package developers who interactively write docs and view the result in their browser. I wrote a bit about how to do it from scratch, how to use Revise etc, but unfortunately Revise does not pick up docs for new function definitions it seems :( so I'm not sure if a Revise-first approach is that great
unfortunately Revise does not pick up docs for new function definitions it seems :( so I'm not sure if a Revise-first approach is that great
Docstring updates work for me on Revise 3.1.4
, with either tracked packages of just using includet
. (Everything should be Revise-first :smiley:)
It would be nice to write a guide targeted for package developers who interactively write docs and view the result in their browser
We're happy to accept PRs for the docs, there's always improvements that could be made.
You are absolutely right :laughing:. It was late yesterday, I forgot to either export the function from the package or reference it properly in the docs :D. I'll make that PR later tonight then.
Hm, still experiencing issues when using Revise. I was writing the following for an interactive package development / docs writing guide, but if you follow along and get to the last step... it doesn't pick up the new function with its docs. Can someone reproduce?
This guide is intended for users who write docs as they develop a new package. For this use case you want to keep a single Julia REPL session open throughout the guide. To keep track of code and docs changes of your package, you need to install Revise.jl globally first. Enter the Pkg REPL by pressing ]
and run:
(@v1.5) pkg> add Revise
julia> using Revise
Go back to the Pkg REPL and generate a new package:
(@v1.5) pkg> generate Example
Generating project Example:
Example/Project.toml
Example/src/Example.jl
Use your favorite editor to create a docs/
folder within the package such that you end up with the following structure (make.jl
and index.md
empty files):
Example/
├── docs
│ ├── make.jl
│ └── src
│ └── index.md
├── Project.toml
└── src
└── Example.jl
Typically Documenter
is not a true dependency of your package, but merely a development tool. Therefore, create a fresh environment in the docs/
folder and add Documenter
and the Example
package itself as dependencies:
(@v1.5) pkg> activate Example/docs
Activating new environment at `~/Documents/projects/Example/docs/Project.toml`
(docs) pkg> add Documenter
(docs) pkg> dev Example
[ Info: Resolving package identifier `Example` as a directory at `~/Documents/projects/Example`.
Open make.jl
in your editor and fill it with the following minimal boilerplate:
using Documenter, Example
makedocs(sitename="My Documentation")
You might also want to add contents to index.md
:
# Example.jl Documentation
Hello world!
In your REPL you can now include the make.jl
script:
julia> cd("Example")
julia> include("docs/make.jl")
[ Info: Precompiling Example [86743d7e-c321-4af5-beac-c79b42746a03]
[ Info: SetupBuildDirectory: setting up build directory.
[ Info: Doctest: running doctests.
[ Info: ExpandTemplates: expanding markdown templates.
[ Info: CrossReferences: building cross-references.
[ Info: CheckDocument: running document checks.
[ Info: Populate: populating indices.
[ Info: RenderDocument: rendering document.
[ Info: HTMLWriter: rendering HTML pages.
The docs/
folder now contains the file build/index.html
. Open this in your browser to view the generated docs.
Next, we add a new function to our package and document it. Replace the contents of Example.jl
with the following:
module Example
export func
"""
func(x)
Returns double the number `x` plus `1`.
"""
func(x) = 2x + 1
end
And document this function in index.md
using
# Example.jl Documentation
```@docs
func(x)
In the REPL we can now include the `make.jl` file once more:
```julia
julia> include("docs/make.jl")
[ Info: SetupBuildDirectory: setting up build directory.
[ Info: Doctest: running doctests.
[ Info: ExpandTemplates: expanding markdown templates.
┌ Warning: no docs found for 'func(x)' in `@docs` block in src/index.md:3-5
│ ```@docs
│ func(x)
│ ```
└ @ Documenter.Expanders ~/.julia/packages/Documenter/pjwqp/src/Expanders.jl:334
[ Info: CrossReferences: building cross-references.
[ Info: CheckDocument: running document checks.
[ Info: Populate: populating indices.
[ Info: RenderDocument: rendering document.
[ Info: HTMLWriter: rendering HTML pages.
Now refresh the index.html
page in your browser
I think you need
```@docs
Example.func(x)
or
makedocs(..., modules=[Example])
?
With both those changes it doesn't seems to work for me:
┌ Warning: no docs found for 'Example.func(x)' in `@docs` block in src/index.md:3-5
│ ```@docs
│ Example.func(x)
│ ```
└ @ Documenter.Expanders ~/.julia/packages/Documenter/pjwqp/src/Expanders.jl:334
Let me try once more from the start... edit: nope. Revise doesn't seem to pick it up for me. That's a bit of a bummer, since it's hard to write a guide that advocates interactive development & viewing docs if this doesn't work out of the box.
I used this pattern all day yesterday and it worked flawlessly...
Hm. And I'm pretty sure I used this approach succesfully 3 years ago too. I wonder what's different here.
Do you have Revise v3?
(@v1.5) pkg> st Revise
Status `~/.julia/environments/v1.5/Project.toml`
[295af30f] Revise v3.1.5
After restarting the REPL it does pick up changes by the way :). Let's see if we can avoid having to put that step in the guide.
Ah, I know what is wrong. Revise
does not track packages recursively into include
, so you need
using Revise, Example
include("docs/make.jl")
Oh, thanks for pointing that out. Only more reasons to document this workflow!
Edit: unfortunately not working (yet) when explicitly using Example
after using Revise
and before the first include("docs/make.jl")
. Will try again later.
Seems like the problem is no new docstrings are picked up if the package had no docstrings in the first place.
I tried to use this approach to generate the docs locally on my Windows 10 machine (julia 1.5.2).
I already had an existing project so I skipped the generate
step but I run:
(docs) pkg> dev MyProject
I get the following error:
Updating registry at `C:\Users\...\.julia\registries\General`
ERROR: The following package names could not be resolved:
* MyProject (36230cab-47f6-4611-a9ad-d42316f9a74f in manifest but not in project)
If I use dev ../MyProject
instead, everything else works the same.
Should this be mentioned as an alternative or am I missing something ?
@Nauss pkg> dev
is relative to the current working directory and the example above assumes you're in the parent directory of MyProject
. In your case, as you're already in MyProject/
, you could just run pkg> dev .
.
Thanks !!
I'm pretty new to Julia and knew I was missing something !
How about adding the following code at the top of default make.jl
file that DocumenterTools.generate
produces:
if abspath(PROGRAM_FILE) == @__FILE__
# When running the `make.jl` file as a script, automatically activate the
# `docs` environment and dev-install the main package into that environment
import Pkg
Pkg.activate(@__DIR__)
Pkg.develop(path=joinpath(@__DIR__, ".."))
Pkg.instantiate()
end
That code snippet could be discussed in more detail in a rewrite of the Documenter Guide.
It would probably help out a lot of people, and with the if abspath(PROGRAM_FILE) == @__FILE__
it wouldn't get in the way of alternative workflows. For example, my own workflow is that I instantiate the test
environment and include(docs/make.jl)
there. This is because I prefer a single REPL where I can interactively run tests, build documentation, or whatever else I might need while developing the package.
I think my preference would be to have it as a separate script (but one that we could definitely auto-generate for the user). I'd prefer not to re-run all the Pkg machinery every time I do julia --project=docs/ docs/make.jl
.
Apologies if I've missed something, but I could not find, either by reading the Documenter docs, or googling, how to generate the docs locally while developing. The correct incantation is present in most travis configs, and was pointed out to me on Slack. Unless I have missed something obvious, I think it would be good to document the commands needed. They are not obvious, at least to me. At the very least, this issue can serve as a reminder to myself, since I had to look it up multiple times over the last months as I developed new packages.
This is what I ended up doing, running from a shell. This presumes that the current directory is the package root, and that there exists a docs specific Project.toml. This project file must contain Documenter and the package in question as depdendencies. The following incantations can add the depedencies required, and generate the manifest
After that, the following incantation runs the doc generation.