Skip to content

Commit

Permalink
Cleanup struct-per-plugin approach
Browse files Browse the repository at this point in the history
Add depreciations, update docstrings, fix tests, and export
Documenter.HTML
  • Loading branch information
adamslc committed Nov 8, 2018
1 parent 5e69443 commit 4c751b8
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 56 deletions.
8 changes: 5 additions & 3 deletions docs/make.jl
Expand Up @@ -45,9 +45,11 @@ makedocs(
],
"contributing.md",
],
# Use clean URLs, unless built as a "local" build
html_prettyurls = !("local" in ARGS),
html_canonical = "https://juliadocs.github.io/Documenter.jl/stable/",
Documenter.HTML(
# Use clean URLs, unless built as a "local" build
prettyurls = !("local" in ARGS),
canonical = "https://juliadocs.github.io/Documenter.jl/stable/",
),
)

deploydocs(
Expand Down
30 changes: 22 additions & 8 deletions src/Documenter.jl
Expand Up @@ -16,6 +16,19 @@ module Documenter
using DocStringExtensions
import Base64: base64decode

"""
Any plugin that needs to either solicit user input or store information in a
[`Documents.Document`](@ref) should create a subtype of [`Plugin`](@ref). The
subtype, `T <: Documenter.Plugin`, must have an empty constructor `T()` that
initialized `T` with the appropriate default values.
To retrieve the values stored in `T`, the plugin can call [`Documents.getplugin`](@ref).
If `T` was passed to [`makedocs`](@ref), the passed type will be returned. Otherwise,
a new `T` object will be created.
"""
abstract type Plugin end


# Submodules
# ----------

Expand All @@ -33,13 +46,13 @@ include("Writers/Writers.jl")
include("Deps.jl")

import .Utilities: Selectors
import .Writers.HTMLWriter: HTML


# User Interface.
# ---------------

export Deps, makedocs, deploydocs, hide

"""
makedocs(
root = "<current-directory>",
Expand Down Expand Up @@ -161,13 +174,14 @@ ignored.
any errors with the document in the previous build phases.
## Output formats
**`format`** allows the output format to be specified. The default value is `:html`, but
additional values are supported via plugins (see below).
The different output formats may require additional keywords to be specified. The
format-specific keywords for the default HTML output are documented at the
[`Writers.HTMLWriter`](@ref) module.
**`format`** allows the output format to be specified. The default value is `:html`. Other
formats can be enabled by using other packages. For examples, see the `DocumenterMarkdown`
and `DocumenterLaTeX` packages.
Documenter is designed to support multiple output formats. By default it is creates a set of
HTML files, but the output format can be controlled with the `format` keyword. The different
output formats may require additional keywords to be specified via plugins. The keywords for
the default HTML output are documented for the [`Writers.HTMLWriter.HTML`](@ref) type.
The default `:html` output format creates a set of HTML files, but Documenter is designed to
support multiple output formats. Via plugin packages, Documenter also supports e.g. Markdown
Expand Down
106 changes: 91 additions & 15 deletions src/Documents.jl
Expand Up @@ -13,7 +13,8 @@ import ..Documenter:
Documenter,
Anchors,
Formats,
Utilities
Utilities,
Plugin

using DocStringExtensions
import Markdown
Expand Down Expand Up @@ -220,8 +221,6 @@ struct Internal
errors::Set{Symbol}
end

abstract type DocumenterPlugin end

# Document.
# ---------

Expand All @@ -231,9 +230,10 @@ Represents an entire document.
struct Document
user :: User # Set by the user via `makedocs`.
internal :: Internal # Computed values.
plugins :: Dict{DataType, DocumenterPlugin}
plugins :: Dict{DataType, Plugin}
end

Document(; kwargs...) = Document(nothing; kwargs...)
function Document(plugins;
root :: AbstractString = Utilities.currentdir(),
source :: AbstractString = "src",
Expand All @@ -253,9 +253,14 @@ function Document(plugins;
sitename :: AbstractString = "",
authors :: AbstractString = "",
analytics :: AbstractString = "",
version :: AbstractString = ""
version :: AbstractString = "",
html_prettyurls :: Union{Bool, Nothing} = nothing, # deprecated
html_disable_git :: Union{Bool, Nothing} = nothing, # deprecated
html_edit_branch :: Union{String, Nothing} = nothing, # deprecated
html_canonical :: Union{String, Nothing} = nothing, # deprecated
others...
)
# Utilities.check_kwargs(others)
Utilities.check_kwargs(others)

fmt = Formats.fmt(format)
@assert !isempty(fmt) "No formats provided."
Expand Down Expand Up @@ -301,20 +306,91 @@ function Document(plugins;
Set{Symbol}()
)

plugin_dict = Dict{DataType, DocumenterPlugin}()
for plugin in plugins
plugin isa DocumenterPlugin ||
throw("$(typeof(plugin)) is not a subtype of `DocumenterPlugin`.")
haskey(plugin_dict, typeof(plugin)) &&
throw("only one copy of $(typeof(plugin)) may be passed.")
plugin_dict[typeof(plugin)] = plugin
plugin_dict = Dict{DataType, Plugin}()
if plugins !== nothing
for plugin in plugins
plugin isa Plugin ||
throw("$(typeof(plugin)) is not a subtype of `Documenter.Plugin`.")
haskey(plugin_dict, typeof(plugin)) &&
throw("only one copy of $(typeof(plugin)) may be passed.")
plugin_dict[typeof(plugin)] = plugin
end
end

# html keywords depreciation
html_keywords = Dict()
if html_prettyurls !== nothing
Base.depwarn("""The `html_prettyurls` keyword argument has been moved to the
`HTML` plugin. To fix this warning, replace
```
html_prettyurls = ...,
```
with
```
HTML(prettyurls = ...),
```
""", :deploydocs)
html_keywords[:prettyurls] = html_prettyurls
end
if html_disable_git !== nothing
Base.depwarn("""The `html_disable_git` keyword argument has been moved to the
`HTML` plugin. To fix this warning, replace
```
html_disable_git = ...,
```
with
```
HTML(disable_git = ...),
```
""", :deploydocs)
html_keywords[:disable_git] = html_disable_git
end
if html_edit_branch !== nothing
Base.depwarn("""The `html_edit_branch` keyword argument has been moved to the
`HTML` plugin. To fix this warning, replace
```
html_edit_branch = ...,
```
with
```
HTML(edit_branch = ...),
```
""", :deploydocs)
html_keywords[:edit_branch] = html_edit_branch
end
if html_canonical !== nothing
Base.depwarn("""The `html_canonical` keyword argument has been moved to the
`HTML` plugin. To fix this warning, replace
```
html_canonical = ...,
```
with
```
HTML(canonical = ...),
```
""", :deploydocs)
html_keywords[:canonical] = html_canonical
end
if !isempty(html_keywords)
if Documenter.Writers.HTMLWriter.HTML in keys(plugin_dict)
throw("Documenter received both an `HTML` plugin and `html_*` keywords.")
end

plugin_dict[Documenter.Writers.HTMLWriter.HTML] =
Documenter.Writers.HTMLWriter.HTML(; html_keywords...)
end

Document(user, internal, plugin_dict)
end

function plugin_settings(doc::Document, type::DataType)
@assert type <: DocumenterPlugin
"""
getplugin(doc::Document, T)
Retrieves the [`Plugin`](@ref) type for `T` stored in `doc`. If `T` was passed to
[`makedocs`](@ref), the passed type will be returned. Otherwise, a new `T` object
will be created using the default constructor `T()`.
"""
function getplugin(doc::Document, type::Type{T}) where T <: Plugin
if !haskey(doc.plugins, type)
doc.plugins[type] = type()
end
Expand Down
1 change: 0 additions & 1 deletion src/Utilities/Utilities.jl
Expand Up @@ -112,7 +112,6 @@ function check_kwargs(kws)
for (k, v) in kws
println(out, " ", k, " = ", v)
end
println(out, "It is possible that the specified format will use these arguments.")
warn(String(take!(out)))
end

Expand Down
62 changes: 38 additions & 24 deletions src/Writers/HTMLWriter.jl
Expand Up @@ -5,7 +5,9 @@ A module for rendering `Document` objects to HTML.
[`HTMLWriter`](@ref) uses the following additional keyword arguments that can be passed to
[`Documenter.makedocs`](@ref): `assets`, `sitename`, `analytics`, `authors`, `pages`,
`version`, `html_prettyurls`, `html_disable_git`.
`version`. The behavior of [`HTMLWriter`](@ref) can be further customized by passing
[`Documenter.makedocs`](@ref) a [`HTML`](@ref), which accepts the following keyword
arguments: `prettyurls`, `disable_git`, `edit_branch`, `canonical`.
**`sitename`** is the site's title displayed in the title bar and at the top of the
*navigation menu. This argument is mandatory for [`HTMLWriter`](@ref).
Expand All @@ -24,27 +26,10 @@ selected option in the version selector. If this is left empty (default) the ver
selector will be hidden. The special value `git-commit` sets the value in the output to
`git:{commit}`, where `{commit}` is the first few characters of the current commit hash.
**`html_prettyurls`** (default `true`) -- allows disabling the pretty URLs feature, which
generates an output directory structre that hides the `.html` suffixes from the URLs (e.g.
by default `src/foo.md` becomes `src/foo/index.html`). This does not work when browsing
documentation in local files since browsers do not resolve `foo/` to `foo/index.html`
for local files. If `html_prettyurls = false`, then Documenter generate `src/foo.html`
instead and sets up the internal links accordingly, suitable for local documentation builds.
**`html_disable_git`** can be used to disable calls to `git` when the document is not
in a Git-controlled repository. Without setting this to `true`, Documenter will throw
an error and exit if any of the Git commands fail. The calls to Git are mainly used to
gather information about the current commit hash and file paths, necessary for constructing
the links to the remote repository.
# `HTML` `Plugin` options
**`html_edit_branch`** specifies which branch, tag or commit the "Edit on GitHub" links
point to. It defaults to `master`. If it set to `nothing`, the current commit will be used.
**`html_canonical`** specifies the canonical URL for your documentation. We recommend
you set this to the base url of your stable documentation, e.g. `https://juliadocs.github.io/Documenter.jl/stable`.
This allows search engines to know which version to send their users to. [See
wikipedia for more information](https://en.wikipedia.org/wiki/Canonical_link_element).
Default is `nothing`, in which case no canonical link is set.
The [`HTML`](@ref) [`Documenter.Plugin`](@ref) provides additional customization options
for the [`HTMLWriter`](@ref). For more information, see the [`HTML`](@ref) documentation.
# Page outline
Expand Down Expand Up @@ -100,8 +85,37 @@ using ...Utilities.MDFlatten

export HTML

# TODO: Document this
struct HTML <: Documents.DocumenterPlugin
"""
HTML(kwargs...)
Sets the behavior of [`HTMLWriter`](@ref).
# Keyword arguments
**`prettyurls`** (default `true`) -- allows disabling the pretty URLs feature, which
generates an output directory structre that hides the `.html` suffixes from the URLs (e.g.
by default `src/foo.md` becomes `src/foo/index.html`). This does not work when browsing
documentation in local files since browsers do not resolve `foo/` to `foo/index.html`
for local files. If `html_prettyurls = false`, then Documenter generate `src/foo.html`
instead and sets up the internal links accordingly, suitable for local documentation builds.
**`disable_git`** can be used to disable calls to `git` when the document is not
in a Git-controlled repository. Without setting this to `true`, Documenter will throw
an error and exit if any of the Git commands fail. The calls to Git are mainly used to
gather information about the current commit hash and file paths, necessary for constructing
the links to the remote repository.
**`edit_branch`** specifies which branch, tag or commit the "Edit on GitHub" links
point to. It defaults to `master`. If it set to `nothing`, the current commit will be used.
**`canonical`** specifies the canonical URL for your documentation. We recommend
you set this to the base url of your stable documentation, e.g. `https://juliadocs.github.io/Documenter.jl/stable`.
This allows search engines to know which version to send their users to. [See
wikipedia for more information](https://en.wikipedia.org/wiki/Canonical_link_element).
Default is `nothing`, in which case no canonical link is set.
"""
struct HTML <: Documenter.Plugin
prettyurls::Bool
disable_git:: Bool
edit_branch:: Union{String, Nothing}
Expand Down Expand Up @@ -138,7 +152,7 @@ mutable struct HTMLContext
search_navnode :: Documents.NavNode
local_assets :: Vector{String}
end
HTMLContext(doc) = HTMLContext(doc, Documents.plugin_settings(doc, HTML), "", [], "", "", IOBuffer(), "", Documents.NavNode("search", "Search", nothing), [])
HTMLContext(doc) = HTMLContext(doc, Documents.getplugin(doc, HTML), "", [], "", "", IOBuffer(), "", Documents.NavNode("search", "Search", nothing), [])

"""
Returns a page (as a [`Documents.Page`](@ref) object) using the [`HTMLContext`](@ref).
Expand Down
13 changes: 8 additions & 5 deletions test/examples/make.jl
Expand Up @@ -116,16 +116,17 @@ examples_html_local_doc = makedocs(
debug = true,
root = examples_root,
build = "builds/html-local",
html_prettyurls = false,
doctestfilters = [r"Ptr{0x[0-9]+}"],
assets = ["assets/custom.css"],
sitename = "Documenter example",
pages = htmlbuild_pages,

linkcheck = true,
linkcheck_ignore = [r"(x|y).md", "z.md", r":func:.*"],

html_edit_branch = nothing,
Documenter.HTML(
prettyurls = false,
edit_branch = nothing,
),
)

# Build with pretty URLs and canonical links
Expand All @@ -134,8 +135,6 @@ examples_html_deploy_doc = makedocs(
debug = true,
root = examples_root,
build = "builds/html-deploy",
html_prettyurls = true,
html_canonical = "https://example.com/stable",
doctestfilters = [r"Ptr{0x[0-9]+}"],
assets = [
"assets/favicon.ico",
Expand All @@ -144,4 +143,8 @@ examples_html_deploy_doc = makedocs(
sitename = "Documenter example",
pages = htmlbuild_pages,
doctest = false,
Documenter.HTML(
prettyurls = true,
canonical = "https://example.com/stable",
)
)

0 comments on commit 4c751b8

Please sign in to comment.