Skip to content

Commit

Permalink
Remove trace of sandbox module in output for at-repl and at-example.
Browse files Browse the repository at this point in the history
  • Loading branch information
fredrikekre committed Jul 7, 2021
1 parent 7cd120e commit 9152ab9
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 4 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

* ![Feature][badge-feature] `@example`- and `@repl`-blocks now support colored output by mapping ANSI escape sequences to HTML. This requires Julia >= 1.6 and passing `ansicolor=true` to `Documenter.HTML` (e.g. `makedocs(format=Documenter.HTML(ansicolor=true, ...), ...)`). In Documenter 0.28.0 this will be the default so to (preemptively) opt-out pass `ansicolor=false`. ([#1441][github-1441], [#1628][github-1628])

* ![Enhancement][badge-enhancement] The sandbox module used for evaluating `@repl` and `@example` blocks is now removed (replaced with `Main`) in text output. ([#1633][github-1633])

* ![Bugfix][badge-bugfix] Dollar signs in the HTML output no longer get accidentally misinterpreted as math delimiters in the browser. ([#890](github-890), [#1625](github-1625))

## Version `v0.27.3`
Expand Down Expand Up @@ -853,6 +855,7 @@
[github-1617]: https://github.com/JuliaDocs/Documenter.jl/pull/1617
[github-1625]: https://github.com/JuliaDocs/Documenter.jl/pull/1625
[github-1628]: https://github.com/JuliaDocs/Documenter.jl/pull/1628
[github-1633]: https://github.com/JuliaDocs/Documenter.jl/pull/1633

[julia-38079]: https://github.com/JuliaLang/julia/issues/38079
[julia-39841]: https://github.com/JuliaLang/julia/pull/39841
Expand Down
23 changes: 19 additions & 4 deletions src/Expanders.jl
Original file line number Diff line number Diff line change
Expand Up @@ -597,19 +597,30 @@ function Selectors.runner(::Type{ExampleBlocks}, x, page, doc)

# Generate different in different formats and let each writer select
output = Base.invokelatest(Utilities.display_dict, result, context = :color => ansicolor)
# Remove references to gensym'd module from text/plain
m = MIME"text/plain"()
if haskey(output, m)
output[m] = remove_sandbox_from_output(output[m], mod)
end

# Only add content when there's actually something to add.
isempty(input) || push!(content, Markdown.Code("julia", input))
if result === nothing
code = Documenter.DocTests.sanitise(buffer)
isempty(code) || push!(content, Dict{MIME,Any}(MIME"text/plain"() => code))
stdouterr = Documenter.DocTests.sanitise(buffer)
stdouterr = remove_sandbox_from_output(stdouterr, mod)
isempty(stdouterr) || push!(content, Dict{MIME,Any}(MIME"text/plain"() => stdouterr))
elseif !isempty(output)
push!(content, output)
end
# ... and finally map the original code block to the newly generated ones.
page.mapping[x] = Documents.MultiOutput(content)
end

# Replace references to gensym'd module with Main
function remove_sandbox_from_output(str, mod::Module)
replace(str, Regex(("(Main\\.)?$(nameof(mod))")) => "Main")
end

# @repl
# -----

Expand Down Expand Up @@ -655,13 +666,17 @@ function Selectors.runner(::Type{REPLBlocks}, x, page, doc)
push!(multicodeblock, Markdown.Code("julia-repl", prepend_prompt(input)))
end
out = IOBuffer()
print(out, c.output)
print(out, c.output) # c.output is std(out|err)
if isempty(input) || isempty(output)
println(out)
else
println(out, output, "\n")
end
push!(multicodeblock, Markdown.Code("documenter-ansi", rstrip(String(take!(out)))))

outstr = String(take!(out))
# Replace references to gensym'd module with Main
outstr = remove_sandbox_from_output(outstr, mod)
push!(multicodeblock, Markdown.Code("documenter-ansi", rstrip(outstr)))
end
page.mapping[x] = Documents.MultiCodeBlock("julia-repl", multicodeblock)
end
Expand Down
66 changes: 66 additions & 0 deletions test/examples/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -506,3 +506,69 @@ julia> function foo end;

I will pay \$1 if $x^2$ is displayed correctly. People may also write \$s or
even money bag\$\$.

# Module scrubbing from `@repl` and `@example`

None of these expressions should result in the gensym'd module in the output

```@repl
@__MODULE__
println("@__MODULE__ is ", @__MODULE__) # sandbox printed to stdout
function f()
println("@__MODULE__ is ", @__MODULE__)
@warn "Main as the module for this log message"
@__MODULE__
end
f()
@warn "Main as the module for this log message"
```
```@repl
module A
function f()
println("@__MODULE__ is ", @__MODULE__)
@warn "Main.A as the module for this log message"
@__MODULE__
end
end
A.f()
```

```@example
@__MODULE__ # sandbox as return value
```

```@example
println("@__MODULE__ is ", @__MODULE__) # sandbox printed to stdout
```

```@example
function f()
println("@__MODULE__ is ", @__MODULE__)
end
f()
```

```@example
function f()
@__MODULE__
end
f()
```

```@example
@warn "Main as the module for this log message"
```

```@example moduleA
module A
function f()
println("@__MODULE__ is ", @__MODULE__)
@warn "Main.A as the module for this log message"
@__MODULE__
end
end
```

```@example moduleA
A.f()
```

0 comments on commit 9152ab9

Please sign in to comment.