Repository: PumasAI/QuartoNotebookRunner.jl (julia)

Issue:
Is it feasible to suppress the module name `Main.Notebook`? 
test.qmd:
````
---
engine: julia
format: pdf
---

```{julia}
struct M a::Int end
x = M(22)
print(x)
```
````
output [test4.pdf](https://github.com/user-attachments/files/15513649/test4.pdf) or:

```
Main.Notebook.M(22)
```
Is it feasible to suppress the module name `Main.Notebook`?

Pull request description:

Patch:
diff --git a/Project.toml b/Project.toml
index e6c89893..d12f7a96 100644
--- a/Project.toml
+++ b/Project.toml
@@ -30,7 +30,7 @@ YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"
 Base64 = "1.6"
 CommonMark = "0.8"
 Compat = "4"
-IOCapture = "0.2"
+IOCapture = "0.2.5"
 InteractiveUtils = "1.6"
 IterTools = "1"
 JSON3 = "1"
diff --git a/src/QuartoNotebookWorker/src/render.jl b/src/QuartoNotebookWorker/src/render.jl
index 86cfba1a..76fedef8 100644
--- a/src/QuartoNotebookWorker/src/render.jl
+++ b/src/QuartoNotebookWorker/src/render.jl
@@ -19,6 +19,7 @@ function render(
                     code;
                     file,
                     line,
+                    cell_options,
                 )
             end,
         )
@@ -173,7 +174,13 @@ function _process_code(
     return _parseall(code; filename, lineno)
 end
 
-function include_str(mod::Module, code::AbstractString; file::AbstractString, line::Integer)
+function include_str(
+    mod::Module,
+    code::AbstractString;
+    file::AbstractString,
+    line::Integer,
+    cell_options::AbstractDict,
+)
     loc = LineNumberNode(line, Symbol(file))
     try
         ast = _process_code(mod, code; filename = file, lineno = line)
@@ -181,7 +188,11 @@ function include_str(mod::Module, code::AbstractString; file::AbstractString, li
         # Note: IO capturing combines stdout and stderr into a single
         # `.output`, but Jupyter notebook spec appears to want them
         # separate. Revisit this if it causes issues.
-        return Packages.IOCapture.capture(; rethrow = InterruptException, color = true) do
+        return Packages.IOCapture.capture(;
+            rethrow = InterruptException,
+            color = true,
+            io_context = _io_context(cell_options),
+        ) do
             result = nothing
             line_and_ex = Expr(:toplevel, loc, nothing)
             try
@@ -223,10 +234,12 @@ end
 
 # passing our module removes Main.Notebook noise when printing types etc.
 function with_context(io::IO, cell_options = Dict{String,Any}())
-    return IOContext(
-        io,
+    return IOContext(io, _io_context(cell_options)...)
+end
+
+function _io_context(cell_options = Dict{String,Any}())
+    return [
         :module => NotebookState.notebook_module(),
-        :color => true,
         :limit => true,
         # This allows a `show` method implementation to check for
         # metadata that may be of relevance to it's rendering. For
@@ -238,7 +251,7 @@ function with_context(io::IO, cell_options = Dict{String,Any}())
         # TODO: perhaps preprocess the metadata provided here rather
         # than just passing it through as-is.
         :QuartoNotebookRunner => (; cell_options, options = NotebookState.OPTIONS[]),
-    )
+    ]
 end
 
 function clean_bt_str(is_error::Bool, bt, err, prefix = "", mimetype = false)


Test patch:
diff --git a/test/examples/io_context.qmd b/test/examples/io_context.qmd
new file mode 100644
index 00000000..f3ddfaaf
--- /dev/null
+++ b/test/examples/io_context.qmd
@@ -0,0 +1,11 @@
+---
+title: io_context
+---
+
+```{julia}
+struct M
+    a::Int
+end
+x = M(22)
+print(x)
+```
diff --git a/test/testsets/io_context.jl b/test/testsets/io_context.jl
new file mode 100644
index 00000000..ee7a7fd5
--- /dev/null
+++ b/test/testsets/io_context.jl
@@ -0,0 +1,12 @@
+include("../utilities/prelude.jl")
+
+test_example(joinpath(@__DIR__, "../examples/io_context.qmd")) do json
+    cells = json["cells"]
+    @test length(cells) == 2
+
+    cell = cells[2]
+    output = cell["outputs"][1]
+    @test output["output_type"] == "stream"
+    @test output["name"] == "stdout"
+    @test output["text"] == "M(22)"
+end