From 0461e2c5f074ca008ddc75d9ead00060e2597f87 Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Wed, 8 Nov 2023 02:55:22 +0100 Subject: [PATCH 1/3] Update julia compat from [1.0.0-2) to [1.6.0-2). --- .github/workflows/ci.yml | 2 +- CHANGELOG.md | 6 +++++- Project.toml | 6 +++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1255c66..51a7380 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: version: - - '1.0' + - '1.6' - '1' - 'nightly' os: diff --git a/CHANGELOG.md b/CHANGELOG.md index 99bb761..b3261c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - +## [Unreleased] +### Changed +- The minimum Julia version requirement for Literate >= 2.16.0 is now 1.6.0 (from 1.0.0). + ([#230][github-230]) ## [2.15.1] - 2023-11-08 ### Fixed @@ -268,6 +271,7 @@ https://discourse.julialang.org/t/ann-literate-jl/10651 for release announcement [github-223]: https://github.com/fredrikekre/Literate.jl/pull/223 [github-228]: https://github.com/fredrikekre/Literate.jl/issues/228 [github-229]: https://github.com/fredrikekre/Literate.jl/pull/229 +[github-230]: https://github.com/fredrikekre/Literate.jl/pull/230 [Unreleased]: https://github.com/fredrikekre/Literate.jl/compare/v2.15.1...HEAD [2.15.1]: https://github.com/fredrikekre/Literate.jl/compare/v2.15.0...v2.15.1 diff --git a/Project.toml b/Project.toml index 2599739..9c252f4 100644 --- a/Project.toml +++ b/Project.toml @@ -9,11 +9,11 @@ JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" [compat] -Base64 = "<0.0.1, 1" +Base64 = "1" IOCapture = "0.2" JSON = "0.18, 0.19, 0.20, 0.21, 1" -REPL = "<0.0.1, 1" -julia = "1" +REPL = "1" +julia = "1.6" [extras] DisplayAs = "0b91fe84-8a4c-11e9-3e1d-67c38462b6d6" From 7503259b9cbcb7c66c6931ccef3472a9ac329f0c Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Wed, 8 Nov 2023 02:30:51 +0100 Subject: [PATCH 2/3] Add soft scoping rule capabilities This patch enables "soft" scoping rules (see e.g. https://github.com/JuliaLang/SoftGlobalScope.jl) for code execution (markdown and notebook output). This is enabled by default for Jupyter notebook output (to mimic how the IJulia kernel works), and disabled otherwise. Soft scope rules can be enabled/disabled with the `softscope :: Bool` configuration variable. Fixes #227. --- CHANGELOG.md | 7 +++++++ src/Literate.jl | 24 +++++++++++++++++------- test/runtests.jl | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 68 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3261c3..680b47f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- "Soft" scoping rules (see e.g. https://github.com/JuliaLang/SoftGlobalScope.jl) are now + available for code execution (markdown and notebook output). This is enabled by default + for Jupyter notebook output (to mimic how the IJulia kernel works), and disabled + otherwise. Soft scope rules can be enabled/disabled with the `softscope :: Bool` + configuration variable. ([#227][github-227], [#230][github-230]) ### Changed - The minimum Julia version requirement for Literate >= 2.16.0 is now 1.6.0 (from 1.0.0). ([#230][github-230]) @@ -269,6 +275,7 @@ https://discourse.julialang.org/t/ann-literate-jl/10651 for release announcement [github-221]: https://github.com/fredrikekre/Literate.jl/pull/221 [github-222]: https://github.com/fredrikekre/Literate.jl/issues/222 [github-223]: https://github.com/fredrikekre/Literate.jl/pull/223 +[github-227]: https://github.com/fredrikekre/Literate.jl/issues/227 [github-228]: https://github.com/fredrikekre/Literate.jl/issues/228 [github-229]: https://github.com/fredrikekre/Literate.jl/pull/229 [github-230]: https://github.com/fredrikekre/Literate.jl/pull/230 diff --git a/src/Literate.jl b/src/Literate.jl index f12440c..071fa17 100644 --- a/src/Literate.jl +++ b/src/Literate.jl @@ -312,6 +312,7 @@ function create_configuration(inputfile; user_config, user_kwargs, type=nothing) cfg["flavor"] = type === (:md) ? DocumenterFlavor() : DefaultFlavor() cfg["credit"] = true cfg["mdstrings"] = false + cfg["softscope"] = type === (:nb) ? true : false # on for Jupyter notebooks cfg["keep_comments"] = false cfg["execute"] = type === :md ? false : true cfg["codefence"] = get(user_config, "flavor", cfg["flavor"]) isa DocumenterFlavor && @@ -408,6 +409,8 @@ Available options: - `devurl` (default: `"dev"`): URL for "in-development" docs, see [Documenter docs] (https://juliadocs.github.io/Documenter.jl/). Unused if `repo_root_url`/ `nbviewer_root_url`/`binder_root_url` are set. +- `softscope` (default: `true` for Jupyter notebooks, `false` otherwise): enable/disable + "soft" scoping rules when executing, see e.g. https://github.com/JuliaLang/SoftGlobalScope.jl. - `repo_root_url`: URL to the root of the repository. Determined automatically on Travis CI, GitHub Actions and GitLab CI. Used for `@__REPO_ROOT_URL__`. - `nbviewer_root_url`: URL to the root of the repository as seen on nbviewer. Determined @@ -580,6 +583,7 @@ function markdown(inputfile, outputdir=pwd(); config::AbstractDict=Dict(), kwarg flavor=config["flavor"], image_formats=config["image_formats"], file_prefix="$(config["name"])-$(chunknum)", + softscope=config["softscope"], ) end end @@ -597,9 +601,10 @@ end function execute_markdown!(io::IO, sb::Module, block::String, outputdir; inputfile::String, fake_source::String, - flavor::AbstractFlavor, image_formats::Vector, file_prefix::String) + flavor::AbstractFlavor, image_formats::Vector, file_prefix::String, + softscope::Bool) # TODO: Deal with explicit display(...) calls - r, str, _ = execute_block(sb, block; inputfile=inputfile, fake_source=fake_source) + r, str, _ = execute_block(sb, block; inputfile=inputfile, fake_source=fake_source, softscope=softscope) # issue #101: consecutive codefenced blocks need newline # issue #144: quadruple backticks allow for triple backticks in the output plain_fence = "\n````\n" => "\n````" @@ -734,7 +739,8 @@ function jupyter_notebook(chunks, config) try cd(config["literate_outputdir"]) do nb = execute_notebook(nb; inputfile=config["literate_inputfile"], - fake_source=config["literate_outputfile"]) + fake_source=config["literate_outputfile"], + softscope=config["softscope"]) end catch err @error "error when executing notebook based on input file: " * @@ -745,7 +751,7 @@ function jupyter_notebook(chunks, config) return nb end -function execute_notebook(nb; inputfile::String, fake_source::String) +function execute_notebook(nb; inputfile::String, fake_source::String, softscope::Bool) sb = sandbox() execution_count = 0 for cell in nb["cells"] @@ -753,7 +759,7 @@ function execute_notebook(nb; inputfile::String, fake_source::String) execution_count += 1 cell["execution_count"] = execution_count block = join(cell["source"]) - r, str, display_dicts = execute_block(sb, block; inputfile=inputfile, fake_source=fake_source) + r, str, display_dicts = execute_block(sb, block; inputfile=inputfile, fake_source=fake_source, softscope=softscope) # str should go into stream if !isempty(str) @@ -835,7 +841,7 @@ function Base.display(ld::LiterateDisplay, mime::MIME, x) end # Execute a code-block in a module and capture stdout/stderr and the result -function execute_block(sb::Module, block::String; inputfile::String, fake_source::String) +function execute_block(sb::Module, block::String; inputfile::String, fake_source::String, softscope::Bool) @debug """execute_block($sb, block) ``` $(block) @@ -851,7 +857,11 @@ function execute_block(sb::Module, block::String; inputfile::String, fake_source # `rethrow = Union{}` means that we try-catch all the exceptions thrown in the do-block # and return them via the return value (they get handled below). c = IOCapture.capture(rethrow = Union{}) do - include_string(sb, block, fake_source) + if softscope + include_string(REPL.softscope, sb, block, fake_source) + else + include_string(sb, block, fake_source) + end end popdisplay(disp) # IOCapture.capture has a try-catch so should always end up here if c.error diff --git a/test/runtests.jl b/test/runtests.jl index d56f304..419838f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -905,6 +905,27 @@ end end Literate.markdown(inputfile, relpath(outdir); execute=true, flavor=Literate.CommonMarkFlavor()) @test read(joinpath(outdir, "inputfile-1.svg"), String) == "issue228" + + # Softscope + write( + inputfile, + """ + ret = 0 + for k = 1:10 + ret += k + end + println("ret = ", ret) + """ + ) + Literate.markdown(inputfile, outdir; execute=true, softscope=true) + @test occursin("ret = 55", read(joinpath(outdir, "inputfile.md"), String)) + ## Disabled softscope + try + Literate.markdown(inputfile, outdir; execute=true, softscope=false) + error("unreachable") + catch err + @test occursin(r"`?ret`? not defined", sprint(Base.showerror, err)) + end end # cd(sandbox) end # mktemp end end @@ -1319,8 +1340,29 @@ end end @test keys(cellout[1]["data"]) == Set(("text/latex",)) @test cellout[1]["data"]["text/latex"] == "DF(4) as text/latex" @test !haskey(cellout[1], "execution_count") - end - end + + # Softscope + write( + inputfile, + """ + ret = 0 + for k = 1:10 + ret += k + end + println("ret = ", ret) + """ + ) + Literate.notebook(inputfile, outdir) + @test occursin("ret = 55", read(joinpath(outdir, "inputfile.ipynb"), String)) + ## Disabled softscope + try + Literate.notebook(inputfile, outdir; softscope=false) + error("unreachable") + catch err + @test occursin(r"`?ret`? not defined", sprint(Base.showerror, err)) + end + end # cd(sandbox) + end # mktempdir end end @testset "Configuration" begin; Base.CoreLogging.with_logger(Base.CoreLogging.NullLogger()) do From 2ac19ef7d70703dfe2e4e1dff8d158a68495fd5d Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Wed, 8 Nov 2023 03:13:08 +0100 Subject: [PATCH 3/3] Set version to 2.16.0. --- CHANGELOG.md | 7 +++++-- Project.toml | 2 +- docs/Manifest.toml | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 680b47f..d004c61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] + + +## [2.16.0] - 2023-11-08 ### Added - "Soft" scoping rules (see e.g. https://github.com/JuliaLang/SoftGlobalScope.jl) are now available for code execution (markdown and notebook output). This is enabled by default @@ -280,7 +282,8 @@ https://discourse.julialang.org/t/ann-literate-jl/10651 for release announcement [github-229]: https://github.com/fredrikekre/Literate.jl/pull/229 [github-230]: https://github.com/fredrikekre/Literate.jl/pull/230 -[Unreleased]: https://github.com/fredrikekre/Literate.jl/compare/v2.15.1...HEAD +[Unreleased]: https://github.com/fredrikekre/Literate.jl/compare/v2.16.0...HEAD +[2.16.0]: https://github.com/fredrikekre/Literate.jl/compare/v2.15.1...v2.16.0 [2.15.1]: https://github.com/fredrikekre/Literate.jl/compare/v2.15.0...v2.15.1 [2.15.0]: https://github.com/fredrikekre/Literate.jl/compare/v2.14.2...v2.15.0 [2.14.2]: https://github.com/fredrikekre/Literate.jl/compare/v2.14.1...v2.14.2 diff --git a/Project.toml b/Project.toml index 9c252f4..c869e9e 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "Literate" uuid = "98b081ad-f1c9-55d3-8b20-4c87d4299306" -version = "2.15.1" +version = "2.16.0" [deps] Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" diff --git a/docs/Manifest.toml b/docs/Manifest.toml index d43c01f..16e04cc 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -420,7 +420,7 @@ uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" deps = ["Base64", "IOCapture", "JSON", "REPL"] path = ".." uuid = "98b081ad-f1c9-55d3-8b20-4c87d4299306" -version = "2.15.1" +version = "2.16.0" [[LogExpFunctions]] deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"]