The lecture notes for an open courseware class I’m working through uses an interactive Pluto notebook. I wanted to add an empty cell to my local copy of this notebook to work on one of the programming exrcises, but the keyboard gesture for doing that wasn’t working for me (in Google Chrome).
My question isn’t about the Pluto UI though. I saw the structure of the notebook file and decided it would be easy enough to write a command line tool that would add a cell to the notebook so long as the notebook wasn’t currently being served. Before diving in to doing uninforned file manipulation, I looked through Pluto.jl and found it was easy to identify a set of functions my program could call into to open and manipulate the notebook.
The present state of my effort is on GitHub:
Im using insert! to insert a new Pluto.Cell into the Pluto.Notebook’s cells vector. I don’t understand why this isn’t working in my application but does work in some stripped down test cases.
My problem is that the length assertion is failing:
“”" new_cell before/after notebook_path relative_to_cell_id
Insert a new, enpty cell before or after the cell specified by existing_cell_id.
The id of the new cell is returned.
function new_cell(ctx::Context, before_after::String, notebook_path::String, relative_to_cell_id::String)::String
notebook = get_notebook(notebook_path)
index = find_cell(notebook, relative_to_cell_id)
rel = validate_option(before_after, :before, :after)
@assert index >= 1
@assert index <= length(notebook.cells)
if rel == :after
index = index + 1
cell = Pluto.Cell()
len = length(notebook.cells)
insert!(notebook.cells, index, cell)
@assert length(notebook.cells) == len + 1
@printf(ctx.stdout, “Inserted new cell %s\n”, string(cell.cell_id))
I’ve tried some stripped down examples, which both work:
As a lisp programmer I’ve learned that “modify in place” operations might need to relocate the object (in this case insert! aND THE Notebook’S vector of Cells), so one should assign the modified result back where it came from. I don’t seem to be able to write to notebook.cells though. If I do
notebook.cells = insert!(notebook.cells, index, cell)
I get the error " type Notebook has no field cells" which is somewhat misdirecting in that I was able to read the cells field without error, just bot set it. I remember reading someplace that Julia didn’t allow cross-module struct mutations.
I also tried using setfield!, but I don’t know how to refer to :cell from the Pluto module rather than my own.
I’ve tried searching the Pluto package for code that modifies Notebook.cells but didn’t find anything. It must be there someplace though otherwise how can people edit their notebooks.