This packages exports a single macro @plutoinclude
which is a simplified version of the @plutoinclude
macro which was exported by PlutoDevMacros.jl up to version v0.7.
This macro tries to simplify the process of including a julia file inside a Pluto notebook with the possibility of reloading the file once its contents are updated. The target file can be any valid julia file (including another Pluto notebook), and this macro simply performs the following steps:
- Create an empty temporary module (outside of the Pluto workspace)
- Include the target file within the temporary module
- Explicitly imports (from the module created in 1.) the names defined in the included file in the current Pluto workspace
You can check the test_notebook.jl file in the test folder (or the Video Examples) for some more usage examples.
Note
The temporary module is created during macro expansion time in order to be able to extract the names and explicitly import them in the expression generated by the macro. This means that reloading the contents of the file can only be done by manually reloading the cell containing the @plutoinclude
macro.
Important
Any package that is imported or used within the included file must also be present in the environment of the notebook calling the @plutoinclude
macro.
This macro tries to be as simple as possible and does not handles the environment of the included file. For more complex cases, consider using the other macros defined in PlutoDevMacros.jl
The path to the file to be included can be specified either as a plain String
, or as any expression that will evaluate to a String in the caller module (i.e. the Pluto workspace where the @plutoinclude
macro is called).
An example use of @plutoinclude
is fed a path as input based on a variable defined in the notebook is the following:
Warning
When specifying the path as an expression depending on variables/functions defined in the notebook itself, the @plutoinclude
macro might behave strangely as the code loading is happening during macro expansion. The following two strange behaviors are important to know about when using variables/functions defined within the notebook as input to the macro:
- The cell containing the macro might error when running for the first time after opening a notebook, depending on the cell loading order within the notebook. This is because the symbol/function is evaluated during the first macro expansion, so before the cell definining the symbol/function is first executed. This can easily be solved by manually re-running the cell with
@plutoinclude
. - The
@plutoinclude
macro will not reload the contents of the file upon reactive run (i.e. when the cell is ran because one of its dependencies has been changed, and not because it was manually re-run). This is because the macro is not expanded/compiled again upon reactive run, so the module containing the included file will not be re-created.- Since version v0.2.0, the macro will try to catch this behavior and show a warning in the macro cell when this happens, prompting the user to manually re-run the cell. See the Video Examples.
The names to be introduced into the Pluto workspace are simply extracted from the temporary module using Base.names(tempmodule)
, and filtering out some of the output names (e.g. gensym
-ed names and other like eval
and include
).
By default, the call to Base.names
will have the all
keyword argument set to true in order to export all names defined directly within the included file.
The @plutoinclude
macro accepts as additional inputs any number of assignments expression of the form name = value
where value
must be a Bool
. These expression are parsed at the beginning of the macro expansion and grouped as kwargs
that are passed to the Base.names
call. One could example set the all
kwarg to false as in the example below:
Note
Setting all
to false
will not export any name defined in the included file unless something is explicitly marked with export
or public
within the file.
Note
If you want to avoid exporting some specific variables from an included Pluto notebook, like for example the variables defined with @bind
, consider marking them in the original notebook as Disabled in file, so they will be commented out in the source file and will not be included in the temporary module generated by @plutoinclude
.
Files that only contain a single module definition are treated differently. The macro, in this case, will import in the calling (Pluto) workspace the names extracted from this single module, instead of the names at the file top-level (which would only be the module's name).
The functionality provided by the @plutoinclude
macro is very similar to the @ingredients
macro from PlutoLinks.jl. The main difference is the fact that while @ingredients
does not explicitly import any name inside the calling Pluto notebook, @plutoinclude
does.
This often simplifies interactive development as one does not need to always prepend the module name to access the variables defined within the file
Note
@ingredients
also tracks changes in the file and rerun dependent cells when updating the file. While a mode supporting Revise
is planned for the next release of SimplePlutoInclude, automatic reload of dependent cells is not planned for this macro as the reload of the file is intended to only be done manually to accidentally avoid triggering long-running cells each time a file is changed.
The following 3 video examples will show warnings that the macro throws when the path is specified as a symbol (and not directly as a string) and the path or contents of the pointed files are changed
0d4a7233-185a-45b2-bf12-a549f9d3c2fd.mp4
3f8e634c-ef8c-4c14-8c36-b687383a1aef.mp4
d3de18b3-69f8-41b4-b1ce-baa7ddaa5cb0.mp4
This is an example showing that files containing a single module definition are treated by importing the names defined within the module itself (instead of the normal behavior that will only see the module as variable generated by the file):
f8278a86-fa0c-42ed-8233-0deaf903e50c.mp4
When a file is imported via @plutoinclude
and no variables are extracted from it, the macro will output a warning. This is mostly happening when the all
keyword is specifically set to false
, as shown below: