Skip to content

Commit

Permalink
Merge pull request #236 from MichaelHatherly/mh/backports
Browse files Browse the repository at this point in the history
Backport #233, #234, #238, #239 to 0.3
  • Loading branch information
mortenpi authored Aug 26, 2016
2 parents aceb2b2 + e069711 commit a40fa71
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 58 deletions.
5 changes: 5 additions & 0 deletions assets/html/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,11 @@ nav.toc ul.internal {
list-style: none;
}

nav.toc ul.internal li.toplevel {
border-top: 1px solid #c9c9c9;
font-weight: bold;
}

nav.toc .toctext {
padding-top: 0.3em;
padding-bottom: 0.3em;
Expand Down
77 changes: 37 additions & 40 deletions docs/src/man/hosting.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,16 @@ package repository:

- travis buildbots startup and run your tests;
- each buildbot will build the package docs using your `docs/make.jl` script;
- a single buildbot will then try to push the generated docs back to github.
- a single buildbot will then try to push the generated docs back to GitHub.

Note that the hosted documentation does not update when you make pull
requests; you see updates only when you merge to `master` or push new tags.

The following sections outline how to enable this for your own package.

## Deploy Keys
## SSH Deploy Keys

Two methods are available for securely deploying generated documentation from Travis to
GitHub. The first method listed below is the preferred approach. The second, and original,
method should be avoided whenever possible.

### SSH Deploy Keys

Deploy keys provide push access to a *single* repository.
Deploy keys provide push access to a *single* repository, to allow secure deployment of generated documentation from Travis to GitHub.

!!! note

Expand All @@ -62,49 +56,52 @@ julia> Travis.genkeys("MyPackage")

where `"MyPackage"` is the name of the package you would like to create deploy keys for.

You may be asked to enter your password for Travis during this process. Once complete you
will need to add the public key displayed in the REPL to your repository -- just follow the
instructions displayed in the REPL.
If you see a line about adding an `openssl` command to your
`.travis.yml` file, you can ignore that (Documenter will handle that
for you).
You may be asked to enter your password for Travis during this process. After one or two questions, and some other reporting, you may also be told to alter your `.travis.yml` file:

Then close the REPL and commit the `docs/.documenter.enc` file that was generated by
[`Travis.genkeys`](@ref) to the repository. You can skip the [GitHub Security Tokens](@ref)
section and move straight on to [Travis Environment Settings](@ref) now.
```
Please add the following to your build script (before_install stage in your .travis.yml, for instance):
If you don't get a `docs/.documenter.enc` file, one possible reason is
an outdated version of `travis`. At the time of this writing, version 1.8.2
was known to work.
openssl aes-256-cbc -K $encrypted_<something>_key -iv $encrypted_<something>_iv -in .documenter.enc -out .documenter -d
### GitHub Security Tokens
Pro Tip: You can add it automatically by running with --add.
```

These tokens provide push access to *every* repository owned by the user.
**Ignore this**. Documenter will handle it for you.

Firstly, generate a new [personal access token](https://github.com/settings/tokens).
Once complete you will need to add the public key displayed in the REPL to your repository -- just follow the instructions displayed in the REPL:

Enter a description for this new token. We'll be calling ours "Travis", but any other name
will do. For the "Select scopes" option choose "public_repo" **only**. Then generate the
token and save it somewhere safe. We'll be needing it during the next section.
```
Make sure to add .documenter.enc to the git repository.
## Travis Environment Settings
Make sure not to add .documenter to the git repository.
Commit all changes to your .travis.yml.
WARNING: removing private key.
### SSH Keys
Add the following public deploy key to '<username>/MyPackage.jl' with write access
If you used [`Travis.genkeys`](@ref) in the previous step then you should go to your Travis
settings page and check that two new keys have been added with names similar to the following
ssh-rsa [...] [email protected]
- `encrypted_e6b49e69746a_key`
- `encrypted_e6b49e69746a_iv`
on the following page:
https://github.com/<username>/MyPackage.jl/settings/keys
### Tokens
Then commit the '.documenter.enc' file. Do not edit '.travis.yml'.
If you generated a GitHub token during the previous step then we'll add the token to our
repository's Travis page. Go to the settings page for the repository and under the
"Environment Variables" section add a new variable called `GITHUB_API_KEY`. Copy the
generated key from the [GitHub Security Tokens](@ref) section as the value and **make sure**
that "Display value in build log" is **off**. Be careful to remove any leading white-space
from the key. Then add the key.
WARNING: removing public key.
```

where `<username>` is your GitHub username, or the name of the organization that hosts the package, and `[...]` is the actual public key that has been generated. Once you've added the public deploy key to GitHub, then close the REPL and commit the `docs/.documenter.enc` file that was generated by [`Travis.genkeys`](@ref) to the repository.

If you don't get a `docs/.documenter.enc` file, one possible reason is
an outdated version of `travis`. At the time of this writing, version 1.8.2
was known to work.

## Travis Environment Settings

You should now go to your Travis settings page and check that two new keys have been added with names similar to the following

- `encrypted_e6b49e69746a_key`
- `encrypted_e6b49e69746a_iv`

## `.travis.yml` Configuration

Expand Down
6 changes: 4 additions & 2 deletions src/Documents.jl
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ immutable EvalNode
result :: Any
end

immutable RawHTML
code::String
end

# Navigation
# ----------------------

Expand Down Expand Up @@ -286,7 +290,6 @@ function populate!(index::IndexNode, document::Document)
# Include *all* signatures, whether they are `Union{}` or not.
cat = Symbol(lowercase(Utilities.doccat(object.binding, Union{})))
if _isvalid(page, index.pages) && _isvalid(mod, index.modules) && _isvalid(cat, index.order)
page = Formats.extension(document.user.format, page)
push!(index.elements, (object, doc, page, mod, cat))
end
end
Expand All @@ -311,7 +314,6 @@ function populate!(contents::ContentsNode, document::Document)
for anchor in anchors
page = relpath(anchor.file, dirname(contents.build))
if _isvalid(page, contents.pages) && Utilities.header_level(anchor.object) contents.depth
page = Formats.extension(document.user.format, page)
push!(contents.elements, (anchor.order, page, anchor))
end
end
Expand Down
9 changes: 7 additions & 2 deletions src/Expanders.jl
Original file line number Diff line number Diff line change
Expand Up @@ -449,10 +449,15 @@ function Selectors.runner(::Type{ExampleBlocks}, x, page, doc)
# Splice the input and output into the document.
content = []
input = droplines(x.code)
output = Documenter.DocChecks.result_to_string(buffer, result)

# Special-case support for displaying SVG graphics. TODO: make this more general.
output = mimewritable(MIME"image/svg+xml"(), result) ?
Documents.RawHTML(stringmime(MIME"image/svg+xml"(), result)) :
Markdown.Code(Documenter.DocChecks.result_to_string(buffer, result))

# Only add content when there's actually something to add.
isempty(input) || push!(content, Markdown.Code("julia", input))
isempty(output) || push!(content, Markdown.Code(output))
isempty(output.code) || push!(content, output)
# ... and finally map the original code block to the newly generated ones.
page.mapping[x] = Markdown.MD(content)
end
Expand Down
4 changes: 3 additions & 1 deletion src/Utilities/DOM.jl
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,9 @@ attributes!(out, s::Symbol) = push!(out, tostr(s => ""))
attributes!(out, p::Pair) = push!(out, tostr(p))

function Base.show(io::IO, n::Node)
if n.name === TEXT
if n.name === Symbol("#RAW#")
print(io, n.nodes[1].text)
elseif n.name === TEXT
print(io, escapehtml(n.text))
else
print(io, '<', n.name)
Expand Down
2 changes: 2 additions & 0 deletions src/Walkers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ walk(f, meta, block::Expanders.DocsNode) = walk(f, meta, block.docstr)

walk(f, meta, block::Expanders.EvalNode) = walk(f, meta, block.result)

walk(f, meta, block::Documents.RawHTML) = nothing

walk(f, meta, block::Expanders.MetaNode) = (merge!(meta, block.dict); nothing)

typealias MDTextElements Union{
Expand Down
52 changes: 40 additions & 12 deletions src/Writers/HTMLWriter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@
Provides the [`render`](@ref) methods to write the documentation as HTML files
(`MIME"text/html"`).
# Page outline
The [`HTMLWriter`](@ref) makes use of the page outline that is determined by the
headings. It is assumed that if the very first block of a page is a level 1 heading,
then it is intended as the page title. This has two consequences:
1. It is then used to automatically determine the page title in the navigation menu
and in the `<title>` tag, unless specified in the `.pages` option.
2. If the first heading is interpreted as being the page title, it is not displayed
in the navigation sidebar.
# Default and custom assets
Documenter copies all files under the source directory (e.g. `/docs/src/`) over
Expand Down Expand Up @@ -290,8 +301,9 @@ function navitem(ctx, current, nn::Documents.NavNode)
if nn === current && !isnull(nn.page)
subs = collect_subsections(ctx.doc.internal.pages[get(nn.page)])
internal_links = map(subs) do _
anchor, text = _
li(a[".toctext", :href => anchor](mdconvert(text)))
istoplevel, anchor, text = _
_li = istoplevel ? li[".toplevel"] : li[]
_li(a[".toctext", :href => anchor](mdconvert(text)))
end
push!(item.nodes, ul[".internal"](internal_links))
end
Expand Down Expand Up @@ -457,6 +469,7 @@ function domify(ctx, navnode, contents::Documents.ContentsNode)
@tags a
lb = ListBuilder()
for (count, path, anchor) in contents.elements
path = Formats.extension(ctx.doc.user.format, path)
header = anchor.object
url = string(path, '#', anchor.id, '-', anchor.nth)
node = a[:href=>url](mdconvert(header.text))
Expand All @@ -470,6 +483,7 @@ function domify(ctx, navnode, index::Documents.IndexNode)
@tags a code li ul
lis = map(index.elements) do _
object, doc, page, mod, cat = _
page = Formats.extension(ctx.doc.user.format, page)
url = string(page, "#", Utilities.slugify(object))
li(a[:href=>url](code("$(object.binding)")))
end
Expand Down Expand Up @@ -554,12 +568,17 @@ end
Tries to guess the page title by looking at the `<h1>` headers and returns the
header contents as a `Nullable` (nulled if the algorithm was unable to determine
the header).
It is assumed that the intended page title can only be guessed if the very first
block of the page is `<h1>` heading. If there is something before the first heading
or the first heading is a lower level heading, then the return value is nulled.
"""
function pagetitle(page::Documents.Page)
for e in page.elements
isa(e, Base.Markdown.Header{1}) && return Nullable{Any}(e.text)
if length(page.elements) >= 1 && isa(page.elements[1], Base.Markdown.Header{1})
Nullable{Any}(page.elements[1].text)
else
Nullable{Any}()
end
return Nullable{Any}()
end

function pagetitle(ctx, navnode::Documents.NavNode)
Expand All @@ -574,15 +593,22 @@ function pagetitle(ctx, navnode::Documents.NavNode)
end

"""
Returns a list of tuples `(anchor, text)`, corresponding to all level 2 headers.
Returns an ordered list of tuples `(toplevel, anchor, text)`, corresponding to
level 1 and 2 headings on the page. The only exception is if the first block on
the page also happens to be a level 1 heading. In that case it is assumed to be
the page title and is dropped from the list of subsections.
"""
function collect_subsections(page::Documents.Page)
# TODO: Should probably be replaced by a proper outline algorithm.
# Currently we ignore the case when there are multiple h1-s.
hs = filter(e -> isa(e, Base.Markdown.Header{2}), page.elements)
map(hs) do e
anchor = page.mapping[e]
"#$(anchor.id)-$(anchor.nth)", e.text
hs = filter(enumerate(page.elements)) do _
idx, element = _
isa(element, Base.Markdown.Header) || return false # ignore non-headers
(idx == 1) && (Utilities.header_level(element) == 1) && return false # if first elem. <h1> => ignored
Utilities.header_level(element) <= 2 # only let <h1> and <h2> through
end
map(hs) do _
idx, heading = _
anchor = page.mapping[heading]
(Utilities.header_level(heading) == 1), "#$(anchor.id)-$(anchor.nth)", heading.text
end
end

Expand Down Expand Up @@ -684,4 +710,6 @@ else
isordered(a::Markdown.List) = a.ordered::Bool
end

mdconvert(html::Documents.RawHTML, parent) = Tag(Symbol("#RAW#"))(html.code)

end
4 changes: 3 additions & 1 deletion src/Writers/MarkdownWriter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ end
## Index, Contents, and Eval Nodes.

function render(io::IO, ::MIME"text/plain", index::Documents.IndexNode, page, doc)
for (object, doc, page, mod, cat) in index.elements
for (object, _, page, mod, cat) in index.elements
page = Formats.extension(doc.user.format, page)
url = string(page, "#", Utilities.slugify(object))
println(io, "- [`", object.binding, "`](", url, ")")
end
Expand All @@ -112,6 +113,7 @@ end

function render(io::IO, ::MIME"text/plain", contents::Documents.ContentsNode, page, doc)
for (count, path, anchor) in contents.elements
path = Formats.extension(doc.user.format, path)
header = anchor.object
url = string(path, '#', anchor.id, '-', anchor.nth)
link = Markdown.Link(header.text, url)
Expand Down

0 comments on commit a40fa71

Please sign in to comment.