# Interaction between \`Logging.jl\`, \`JuliaFormatter.jl\` and \`Documenter.jl\`?

**URL:** <https://discourse.julialang.org/t/interaction-between-logging-jl-juliaformatter-jl-and-documenter-jl/93504>\
**Category:** General Usage\
**Tags:** documentation, documenter, markdown, logging, formatting\
**Created:** [January 25, 2023, 12:26pm UTC](https://discourse.julialang.org/t/interaction-between-logging-jl-juliaformatter-jl-and-documenter-jl/93504 "2023-01-25T12:26:48Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![iago-lito](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iago-lito/32/31924_2.png) [@iago-lito](https://discourse.julialang.org/u/iago-lito)\
**Post date:** [January 25, 2023, 12:26pm UTC](https://discourse.julialang.org/t/interaction-between-logging-jl-juliaformatter-jl-and-documenter-jl/93504/1 "2023-01-25T12:26:48Z")

</div>

Hi there,

I am very confused by the interaction(s?) between `Logging.jl`, `JuliaFormatter.jl` and `Documenter.jl`. My initial problem was that I had blocks like this in my package documentation:

````plaintext
```@example
my_function() # returns 5
```

````

Rendering in the HTML docs as:

```julia
my_function() # returns 5

```

```julia
┌ Warning: My warning message.
└ @ MyModule ~/path/to/my/source/file.jl:42
5

```

I have been willing to remove the warning from the generated docs, because I know it will be fixed in the future and it’s just confusing at this point in the docs. The following does work:

````plaintext
```@example
using Logging # hide
with_logger(NullLogger()) do # hide
my_function()
end # hide    
```

````

Which correctly renders as:

```julia
my_function()

```

```julia
5

```

But then `JuliaFormatter.jl` reformats the example to add the required indentation, which leaves me with the following rather unsatisfying situation:

````plaintext
```@example
using Logging # hide
with_logger(NullLogger()) do # hide
    my_function()
end # hide
```

````

Rendering as:

```julia
    my_function()

```

```julia
5

```

I have tried adding the following lines to leave instructions to `JuliaFormatter.jl` in a way that would _not_ be rendered in the final docs:

```julia
#! format: off
#! format: off # hide
# hide #! format: off

```

None of which worked. So here is my first question then: **How can I use `#! format: off` in my docstrings `@example` blocks?**

I went for another approach then:

````plaintext
```
using Logging # hide
logger_safe = global_logger(NullLogger()) # hide
my_function()
global_logger(logger_safe) # hide
```

````

But this did not work and rendered as:

```julia
my_function()

```

```julia
┌ Warning: My warning message.
└ @ MyModule ~/path/to/my/source/file.jl:42
5

```

**How come `with_logger()` appears to work in docstrings `@example` blocks and yet `global_logger()` does not?**

Since my docs are rather long to generate, I have then decided to toy around with a smaller project just to better understand what is happening here, using the following structure:

```julia
JuliaTests/
├── Manifest.toml
├── Project.toml
└── src/
    ├── JuliaTests.jl
    └── main.md

```

`src/JuliaTests.jl`

```julia
module JuliaTests

function f()
  @info "INFO message"
  @warn "WARN message"
  @error "ERROR message"
  5
end
export f

end # module JuliaTests 

```

`src/main.md`

````plaintext
```@example JuliaTests
using JuliaTests
f()
```

```@example JuliaTests
function g()
  @info "INFO message"
  @warn "WARN message"
  @error "ERROR message"
  8
end

g()
```

````

Then I ran:

```plaintext
$ julia --project=.
julia> using JuliaTests
julia> using Documenter
julia> makedocs(;modules=[JuliaTests], sitename="toy")

```

Only to figure out that the resulting file in `build/main/index.html` was now rendered as:

```julia
using JuliaTests
f()

```

```julia
5

```

```julia
function g()
  @info "INFO message"
  @warn "WARN message"
  @error "ERROR message"
  8
end

g()

```

```julia
8

```

Which confuses me even more, because the logged messages are now _not_ rendered within the resulting docs. My initial problem was to remove the unwanted ones in my actual package.

Why would there be a difference between my package rendering and my MWE? What is `Documenter.jl` policy regarding Logged messages? How can we control whether they should be rendered or not as part of the resulting, generated html doc?

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [January 25, 2023, 1:08pm UTC](https://discourse.julialang.org/t/interaction-between-logging-jl-juliaformatter-jl-and-documenter-jl/93504/2 "2023-01-25T13:08:49Z")

</div>

`with_logger` with `# hide` is what I would recommend, and have used in the past. I don’t know how the formatting markers should (if they can) be used in markdown files.

> [@iago-lito](#):
>
> How come `with_logger()` appears to work in docstrings `@example` blocks and yet `global_logger()` does not?

In order to capture output Documenter replaces the logger before every expression to be evalutated. Your example can be expanded to the following, from which it is clear why the former works, and the latter doesn’t:

```julia
# Setup for Expr #1
old_logger = global_logger(ConsoleLogger(...) # Setup for Expr #1
with_logger(NullLogger()) do # Expr #1
    my_function() # Expr #1
end # Expr #1
global_logger(old_logger) # Tear down for Expr #1

```

```julia
# Setup for Expr #1
old_logger = global_logger(ConsoleLogger(...) # Setup for Expr #1
logger_safe = global_logger(NullLogger()) # Expr #1
global_logger(old_logger) # Tear down for Expr #1

old_logger = global_logger(ConsoleLogger(...) # Setup for Expr #2
my_function() # Expr #2
global_logger(old_logger) # Tear down for Expr #2

old_logger = global_logger(ConsoleLogger(...) # Setup for Expr #3
global_logger(logger_safe) # Expr #3
global_logger(old_logger) # Tear down for Expr #3

```

> [@iago-lito](#):
>
> Why would there be a difference between my package rendering and my MWE? What is `Documenter.jl` policy regarding Logged messages?

The rendered output from an `@example` block is selected in this order:

1. Return value of the block (`8` in your example)
2. `stdout`/`stderr`

If you are truly returning 5 in the first example (`return 5`) then something is a bit off here, because then 2. would never be visible. Are you sure you are not _printing_ 5? For example

````julia
```@example
function warn_and_return_five()
    @warn "Returning 5"
    return 5
end

warn_and_return_five()
```

````

will show

```julia
5

```

whereas

````julia
```@example
function warn_and_print_five()
    @warn "Printing 5"
    println(5)
end

warn_and_print_five()
```

````

will show

```plaintext
┌ Warning: Printing 5
└ @ Main index.md:13
5

```

---

<div class="post-metadata">

**Author:** ![mortenpi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mortenpi/32/158_2.png) [@mortenpi](https://discourse.julialang.org/u/mortenpi)\
**Post date:** [January 25, 2023, 10:54pm UTC](https://discourse.julialang.org/t/interaction-between-logging-jl-juliaformatter-jl-and-documenter-jl/93504/3 "2023-01-25T22:54:57Z")

</div>

I don’t think there is a great solution for the formatting problem right now, but I [opened an issue about it](https://github.com/JuliaDocs/Documenter.jl/issues/2025).

What _might_ work is to put the `#! format:` comments in an otherwise empty at-meta block just before and after:

````markdown
```@meta
#! format: off
```
```@example
using Logging # hide
with_logger(NullLogger()) do # hide
my_function()
end # hide    
```
```@meta
#! format: on
```

````

Empty at-meta blocks should be fine from Documenter’s standpoint, but I don’t know if JuliaFormatter treats each of the code blocks independently or not.

---

<div class="post-metadata">

**Author:** ![iago-lito](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iago-lito/32/31924_2.png) [@iago-lito](https://discourse.julialang.org/u/iago-lito)\
**Post date:** [January 26, 2023, 9:36am UTC](https://discourse.julialang.org/t/interaction-between-logging-jl-juliaformatter-jl-and-documenter-jl/93504/4 "2023-01-26T09:36:58Z")

</div>

> [@fredrikekre](#):
>
> The rendered output from an `@example` block is selected in this order:
> 
> 1. Return value of the block (`8` in your example)
> 2. `stdout`/`stderr`
> 
> If you are truly returning 5 in the first example (`return 5`) then something is a bit off here, because then 2. would never be visible. Are you sure you are not _printing_ 5?

Well, you nailed it 😃 This is _exactly_ the source of my confusion here. I was actually “printing 5”, not because I wrote `println(5)`, but because my actual expected output was the one from `@time my_expression()`, which is indeed just printed on stdout IIUC. This does explain the difference between my MWE and my actual documentation. Thank you \<3

> [@mortenpi](#):
>
> Empty at-meta blocks should be fine from Documenter’s standpoint, but I don’t know if JuliaFormatter treats each of the code blocks independently or not.

Unfortunately it does not seem to work. Maybe as you write, JuliaFormatter treats every block independently?

> [@mortenpi](#):
>
> I don’t think there is a great solution for the formatting problem right now, but I [opened an issue about it](https://github.com/JuliaDocs/Documenter.jl/issues/2025).

Thank you for that \<3 I think this my only way out of here now 🙂
