# Jupyter notebook -- saving code to file?

**URL:** <https://discourse.julialang.org/t/jupyter-notebook-saving-code-to-file/135307>\
**Category:** VS Code\
**Created:** [January 28, 2026, 2:03pm UTC](https://discourse.julialang.org/t/jupyter-notebook-saving-code-to-file/135307 "2026-01-28T14:03:41Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [January 28, 2026, 2:03pm UTC](https://discourse.julialang.org/t/jupyter-notebook-saving-code-to-file/135307/1 "2026-01-28T14:03:41Z")

</div>

I’m using Jupyter notebooks in VSCode to do computations that I want to include in a word processor (LyX for now).

Generating plots is no problem: I just save them to file, and link the plots into the word processor.

**Question** : is there a clean way to save the content of a code cell to file, so that I can link it into a computer listing (of, say LyX)?

MS Copilot suggests to define a macro, say:

```julia
macro save_and_run(path, block)
    # Write the code to a file
    open(path, "w") do io
        print(io, block)
    end
    # Evaluate the code in the caller's scope
    return esc(block)
end

```

and place the code within a macro statement:

```julia
@save_and_run "cell1.jl" begin
    x = 1:10
    y = sum(x)
    println("Sum is $y")
end

```

I have **zero** experience with writing macros. And for all I know, this functionality already exists?? Suggestions are appreciated.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 28, 2026, 3:21pm UTC](https://discourse.julialang.org/t/jupyter-notebook-saving-code-to-file/135307/2 "2026-01-28T15:21:51Z")

</div>

NBInclude.jl has an `nbexport` function to convert a notebook to plain text. Notebook files are just JSON, so you can also use any JSON package like JSON.jl to extract whatever you want.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 28, 2026, 3:24pm UTC](https://discourse.julialang.org/t/jupyter-notebook-saving-code-to-file/135307/3 "2026-01-28T15:24:44Z")

</div>

You can also use `In[n]` in IJulia (including via vscode, if you are using the actual Jupyter kernel instead of vscode’s partial re-implementation) to access the contents of any input code cell as a string.

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [January 28, 2026, 3:28pm UTC](https://discourse.julialang.org/t/jupyter-notebook-saving-code-to-file/135307/4 "2026-01-28T15:28:10Z")

</div>

A problem with this, is that…

- I typically only want to save specific code segments in a notebook
- I may re-arrange the order of content in a notebook (including adding markup code, etc.). This makes it challenging to auto-import code into, say LyX computer listing, because I may change the location of the code that I want to import.

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [January 28, 2026, 3:28pm UTC](https://discourse.julialang.org/t/jupyter-notebook-saving-code-to-file/135307/5 "2026-01-28T15:28:42Z")

</div>

I probably use the VSCode partial re-implementation (?).

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [January 28, 2026, 3:32pm UTC](https://discourse.julialang.org/t/jupyter-notebook-saving-code-to-file/135307/6 "2026-01-28T15:32:42Z")

</div>

After some back and forth with MS Copilot, it (=MSCopilot) came up with the following macro:

```julia
"""
    @save_run path_expr begin
        code...
    end

Write the contents of the block to the file given by `path_expr`,
preserving user comments but removing Jupyter's line-number annotations.
Then evaluate the statements in the caller's scope.
"""
macro save_run(path_expr, block)
    @assert block.head === :block "Second argument must be a `begin ... end` block."

    # Evaluate the path expression in the caller's module
    path = Core.eval( __module__ , path_expr)

    # --- Remove only LineNumberNodes, preserve comments ---
    cleaned_stmts = filter(stmt -> !(stmt isa LineNumberNode), block.args)

    # --- Write each cleaned statement to the file ---
    open(path, "w") do io
        for stmt in cleaned_stmts
            print(io, stmt, "\n")
        end
    end

    # --- Evaluate the cleaned statements in the caller's scope ---
    return Expr(:block, (esc(stmt) for stmt in cleaned_stmts)...)
end

```

Here is an example of running it:

```julia
using Plots

listpath = "..."
listtype = ".jl"

@save_run listpath*"test"*listtype begin
    # Testing comments
    x = range(0,2pi,length=100)
    # Plotting code
    plot(x,sin.(x))
end

```

The code runs in JupyterNotebook as it should. But the implementation is not perfect…

- My comments in the code are stripped off in the produced file
- MS Copilot suggests that indentation I use in code, functions, etc. may be removed

However, MS Copilot suggests that the macro should work in VSCode itself, in Pluto, etc.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 29, 2026, 2:13am UTC](https://discourse.julialang.org/t/jupyter-notebook-saving-code-to-file/135307/7 "2026-01-29T02:13:10Z")

</div>

You can always do:

```julia-auto
code = """
some code
"""
include_string(Main, code)
write(filename, code)

```

to save everything, including comments, no macros required. (But the syntax highlighting won’t work in your editor.)

Otherwise you have to do something specific to the IJulia kernel (which you can select in vscode by choosing the Jupyter kernel).

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [January 29, 2026, 9:22am UTC](https://discourse.julialang.org/t/jupyter-notebook-saving-code-to-file/135307/8 "2026-01-29T09:22:45Z")

</div>

That works fine! I just reverse the order of `include_string` and `write` so that I get the code response in the below the Jupyter Notebook cell.
