From 70ca22dffa0955f8282b705378b84b2dc06d0ea7 Mon Sep 17 00:00:00 2001 From: Deeptendu Santra Date: Mon, 30 Jan 2023 21:30:39 +0530 Subject: [PATCH 1/6] Move pluto to requires --- Project.toml | 5 +---- src/DemoCards.jl | 8 ++++++-- src/types/card.jl | 1 - src/types/pluto.jl | 2 ++ src/utils.jl | 11 ++--------- 5 files changed, 11 insertions(+), 16 deletions(-) diff --git a/Project.toml b/Project.toml index 5d58a281..34cdd476 100644 --- a/Project.toml +++ b/Project.toml @@ -12,15 +12,12 @@ ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" Mustache = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70" -Pluto = "c3e4b0f8-55cb-11ea-2926-15256bba5781" -PlutoStaticHTML = "359b1769-a58e-495b-9770-312e911026ad" +Requires = "ae029012-a4dd-5104-9daa-d747884805df" Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb" YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6" [compat] Documenter = "0.22, 0.23, 0.24, 0.25, 0.26, 0.27" -Pluto = "^0.19.13" -PlutoStaticHTML = "^6" FileIO = "1" HTTP = "0.6, 0.7, 0.8, 0.9, 1" ImageCore = "0.7, 0.8, 0.9" diff --git a/src/DemoCards.jl b/src/DemoCards.jl index ba38ccdf..00d055df 100644 --- a/src/DemoCards.jl +++ b/src/DemoCards.jl @@ -6,8 +6,7 @@ using Mustache using Literate using ImageCore using FileIO, JSON, YAML -using Pluto -using PlutoStaticHTML +using Requires using Suppressor # suppress log generated by 3rd party tools, e.g., Literate import HTTP using Documenter @@ -49,6 +48,11 @@ include("preview.jl") export makedemos, cardtheme, preview_demos +function __init__() + @require Pluto="c3e4b0f8-55cb-11ea-2926-15256bba5781" begin + @require PlutoStaticHTML = "359b1769-a58e-495b-9770-312e911026ad" include("types/pluto.jl") + end +end """ diff --git a/src/types/card.jl b/src/types/card.jl index ab9d1b35..c0806b8d 100644 --- a/src/types/card.jl +++ b/src/types/card.jl @@ -126,4 +126,3 @@ end include("markdown.jl") include("julia.jl") -include("pluto.jl") diff --git a/src/types/pluto.jl b/src/types/pluto.jl index dc91da4e..5b28439e 100644 --- a/src/types/pluto.jl +++ b/src/types/pluto.jl @@ -175,3 +175,5 @@ function make_badges(card::PlutoDemoCard; src, card_dir, nbviewer_root_url, proj join(badges, " ") end + +parse(card::PlutoDemoCard) = Pluto.frontmatter(card.path) diff --git a/src/utils.jl b/src/utils.jl index ab5ac616..4d2f9581 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -189,14 +189,8 @@ Currently supported items are: `title`, `id`, `cover`, `description`. They also need to validate the values. """ function parse(T::Val, card::AbstractDemoCard) - # TODO: generalize - if T === Val(:Pluto) - frontmatter = [] - config = Pluto.frontmatter(card.path) - else - header, frontmatter, body = split_frontmatter(readlines(card.path)) - config = parse(T, body) - end + header, frontmatter, body = split_frontmatter(readlines(card.path)) + config = parse(T, body) # frontmatter has higher priority if !isempty(frontmatter) yaml_config = try @@ -213,7 +207,6 @@ function parse(T::Val, card::AbstractDemoCard) end parse(card::JuliaDemoCard) = parse(Val(:Julia), card) parse(card::MarkdownDemoCard) = parse(Val(:Markdown), card) -parse(card::PlutoDemoCard) = parse(Val(:Pluto), card) function parse(T::Val, contents::String) From 61ac2ccde509f236ef847263f89be73abf8bef85 Mon Sep 17 00:00:00 2001 From: Deeptendu Santra Date: Wed, 1 Feb 2023 01:49:36 +0530 Subject: [PATCH 2/6] Add compat --- Project.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Project.toml b/Project.toml index 34cdd476..90619e03 100644 --- a/Project.toml +++ b/Project.toml @@ -18,6 +18,7 @@ YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6" [compat] Documenter = "0.22, 0.23, 0.24, 0.25, 0.26, 0.27" +Requires = "1.3" FileIO = "1" HTTP = "0.6, 0.7, 0.8, 0.9, 1" ImageCore = "0.7, 0.8, 0.9" From 5b2ea74edbb5a02a09e71b1114740166ab180f1f Mon Sep 17 00:00:00 2001 From: Deeptendu Santra Date: Mon, 6 Feb 2023 01:27:48 +0530 Subject: [PATCH 3/6] Working for julia 1.9 --- Project.toml | 10 +++- ext/PlutoNotebook.jl | 130 +++++++++++++++++++++++++++++++++++++++++++ src/DemoCards.jl | 11 ++-- src/types/card.jl | 1 + src/types/pluto.jl | 107 ----------------------------------- 5 files changed, 147 insertions(+), 112 deletions(-) create mode 100644 ext/PlutoNotebook.jl diff --git a/Project.toml b/Project.toml index 90619e03..0b636d7a 100644 --- a/Project.toml +++ b/Project.toml @@ -16,8 +16,15 @@ Requires = "ae029012-a4dd-5104-9daa-d747884805df" Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb" YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6" +[weakdeps] +PlutoStaticHTML = "359b1769-a58e-495b-9770-312e911026ad" + +[extensions] +PlutoNotebook = "PlutoStaticHTML" + [compat] Documenter = "0.22, 0.23, 0.24, 0.25, 0.26, 0.27" +PlutoStaticHTML = "6" Requires = "1.3" FileIO = "1" HTTP = "0.6, 0.7, 0.8, 0.9, 1" @@ -30,6 +37,7 @@ YAML = "0.3, 0.4" julia = "1.6" [extras] +PlutoStaticHTML = "359b1769-a58e-495b-9770-312e911026ad" ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" ImageShow = "4e3cecfd-b093-5904-9786-8bbb286a6a31" ReferenceTests = "324d217c-45ce-50fc-942e-d289b448e8cf" @@ -37,4 +45,4 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" TestImages = "5e47fb64-e119-507b-a336-dd2b206d9990" [targets] -test = ["ImageMagick", "ImageShow", "ReferenceTests", "Test", "TestImages"] +test = ["ImageMagick", "ImageShow", "ReferenceTests", "Test", "TestImages", "PlutoStaticHTML"] diff --git a/ext/PlutoNotebook.jl b/ext/PlutoNotebook.jl new file mode 100644 index 00000000..c16c0912 --- /dev/null +++ b/ext/PlutoNotebook.jl @@ -0,0 +1,130 @@ +module PlutoNotebook + +using Dates +using DemoCards: AbstractDemoCard +import DemoCards: PlutoDemoCard, save_democards, make_badges, parse +isdefined(Base, :get_extension) ? (using PlutoStaticHTML) : (using ..PlutoStaticHTML) +using PlutoStaticHTML + + +function PlutoDemoCard(path::AbstractString)::PlutoDemoCard + # first consturct an incomplete democard, and then load the config + card = PlutoDemoCard(path, "", "", "", "", "", DateTime(0), JULIA_COMPAT, false) + + config = parse(card) + card.cover = load_config(card, "cover"; config = config) + card.title = load_config(card, "title"; config = config) + card.date = load_config(card, "date"; config = config) + card.author = load_config(card, "author"; config = config) + card.julia = load_config(card, "julia"; config = config) + # default id requires a title + card.id = load_config(card, "id"; config = config) + # default description requires a title + card.description = load_config(card, "description"; config = config) + card.hidden = load_config(card, "hidden"; config = config) + + return card +end + + +""" + save_democards(card_dir::AbstractString, card::PlutoDemoCard; + project_dir, + src, + credit, + nbviewer_root_url) + +process the original julia file and save it. + +The processing pipeline is: + +1. preprocess and copy source file +3. generate markdown file +4. insert header and footer to generated markdown file +""" +function save_democards( + card_dir::AbstractString, + card::PlutoDemoCard; + credit, + nbviewer_root_url, + project_dir = Base.source_dir(), + src = "src", + throw_error = false, + properties = Dict{String,Any}(), + kwargs..., +) + if !isabspath(card_dir) + card_dir = abspath(card_dir) + end + isdir(card_dir) || mkpath(card_dir) + @debug card.path + + # copy to card dir and do things + cardname = splitext(basename(card.path))[1] + # pluto outputs are expensive, we save the output to a cache dir + # these cache dir contains the render files from previous runs, + # saves time, while rendering + render_dir = joinpath(project_dir, "pluto_output") |> abspath + isdir(render_dir) || mkpath(render_dir) + + nb_path = joinpath(card_dir, "$(cardname).jl") + md_path = joinpath(card_dir, "$(cardname).md") + + cp(card.path, nb_path) + + if VERSION < card.julia + # It may work, it may not work; I hope it would work. + @warn "The running Julia version `$(VERSION)` is older than the declared compatible version `$(card.julia)`. You might need to upgrade your Julia." + end + + oopts = OutputOptions(; append_build_context = false) + output_format = documenter_output + bopts = BuildOptions(card_dir; previous_dir = render_dir, output_format = output_format) + # don't run notebooks in parallel + # TODO: User option to run it parallel or not + build_notebooks(bopts, ["$(cardname).jl"], oopts) + + # move rendered files to cache + cache_path = joinpath(render_dir, basename(md_path)) + cp(md_path, cache_path; force = true) + + badges = make_badges( + card; + src = src, + card_dir = card_dir, + nbviewer_root_url = nbviewer_root_url, + project_dir = project_dir, + build_notebook = false, + ) + + header = "# [$(card.title)](@id $(card.id))\n" + footer = pluto_footer + + body = join(readlines(md_path), "\n") + write(md_path, header, badges * "\n\n", body, footer) + + return nothing +end + +function make_badges( + card::PlutoDemoCard; + src, + card_dir, + nbviewer_root_url, + project_dir, + build_notebook, +) + cardname = splitext(basename(card.path))[1] + badges = [] + push!(badges, "[![Source code]($download_badge)]($(cardname).jl)") + + push!(badges, invoke(make_badges, Tuple{AbstractDemoCard}, card)) + + join(badges, " ") +end + +parse(card::PlutoDemoCard) = PlutoStaticHTML.Pluto.frontmatter(card.path) + + + +end diff --git a/src/DemoCards.jl b/src/DemoCards.jl index 00d055df..5a5328ce 100644 --- a/src/DemoCards.jl +++ b/src/DemoCards.jl @@ -6,7 +6,6 @@ using Mustache using Literate using ImageCore using FileIO, JSON, YAML -using Requires using Suppressor # suppress log generated by 3rd party tools, e.g., Literate import HTTP using Documenter @@ -48,10 +47,14 @@ include("preview.jl") export makedemos, cardtheme, preview_demos +if !isdefined(Base, :get_extension) +using Requires +end + function __init__() - @require Pluto="c3e4b0f8-55cb-11ea-2926-15256bba5781" begin - @require PlutoStaticHTML = "359b1769-a58e-495b-9770-312e911026ad" include("types/pluto.jl") - end + @static if !isdefined(Base, :get_extension) + @require PlutoStaticHTML = "359b1769-a58e-495b-9770-312e911026ad" include("../ext/PlutoNotebook.jl") + end end """ diff --git a/src/types/card.jl b/src/types/card.jl index c0806b8d..ab9d1b35 100644 --- a/src/types/card.jl +++ b/src/types/card.jl @@ -126,3 +126,4 @@ end include("markdown.jl") include("julia.jl") +include("pluto.jl") diff --git a/src/types/pluto.jl b/src/types/pluto.jl index 5b28439e..2d3e1436 100644 --- a/src/types/pluto.jl +++ b/src/types/pluto.jl @@ -70,110 +70,3 @@ mutable struct PlutoDemoCard <: AbstractDemoCard hidden::Bool end -function PlutoDemoCard(path::AbstractString)::PlutoDemoCard - # first consturct an incomplete democard, and then load the config - card = PlutoDemoCard(path, "", "", "", "", "", DateTime(0), JULIA_COMPAT, false) - - config = parse(card) - card.cover = load_config(card, "cover"; config=config) - card.title = load_config(card, "title"; config=config) - card.date = load_config(card, "date"; config=config) - card.author = load_config(card, "author"; config=config) - card.julia = load_config(card, "julia"; config=config) - # default id requires a title - card.id = load_config(card, "id"; config=config) - # default description requires a title - card.description = load_config(card, "description"; config=config) - card.hidden = load_config(card, "hidden"; config=config) - - return card -end - - -""" - save_democards(card_dir::AbstractString, card::PlutoDemoCard; - project_dir, - src, - credit, - nbviewer_root_url) - -process the original julia file and save it. - -The processing pipeline is: - -1. preprocess and copy source file -3. generate markdown file -4. insert header and footer to generated markdown file -""" -function save_democards(card_dir::AbstractString, - card::PlutoDemoCard; - credit, - nbviewer_root_url, - project_dir=Base.source_dir(), - src="src", - throw_error = false, - properties = Dict{String, Any}(), - kwargs...) - if !isabspath(card_dir) - card_dir = abspath(card_dir) - end - isdir(card_dir) || mkpath(card_dir) - @debug card.path - - # copy to card dir and do things - cardname = splitext(basename(card.path))[1] - # pluto outputs are expensive, we save the output to a cache dir - # these cache dir contains the render files from previous runs, - # saves time, while rendering - render_dir = joinpath(project_dir, "pluto_output") |> abspath - isdir(render_dir) || mkpath(render_dir) - - nb_path = joinpath(card_dir, "$(cardname).jl") - md_path = joinpath(card_dir, "$(cardname).md") - - cp(card.path, nb_path) - - if VERSION < card.julia - # It may work, it may not work; I hope it would work. - @warn "The running Julia version `$(VERSION)` is older than the declared compatible version `$(card.julia)`. You might need to upgrade your Julia." - end - - oopts = OutputOptions(; append_build_context=false) - output_format = documenter_output - bopts = BuildOptions(card_dir;previous_dir=render_dir, - output_format=output_format) - # don't run notebooks in parallel - # TODO: User option to run it parallel or not - build_notebooks(bopts, ["$(cardname).jl"], oopts) - - # move rendered files to cache - cache_path = joinpath(render_dir, basename(md_path)) - cp(md_path, cache_path; force=true) - - badges = make_badges(card; - src=src, - card_dir=card_dir, - nbviewer_root_url=nbviewer_root_url, - project_dir=project_dir, - build_notebook=false) - - header = "# [$(card.title)](@id $(card.id))\n" - footer = pluto_footer - - body = join(readlines(md_path), "\n") - write(md_path, header, badges * "\n\n", body, footer) - - return nothing -end - -function make_badges(card::PlutoDemoCard; src, card_dir, nbviewer_root_url, project_dir, build_notebook) - cardname = splitext(basename(card.path))[1] - badges = [] - push!(badges, "[![Source code]($download_badge)]($(cardname).jl)") - - push!(badges, invoke(make_badges, Tuple{AbstractDemoCard}, card)) - - join(badges, " ") -end - -parse(card::PlutoDemoCard) = Pluto.frontmatter(card.path) From 1dd7fc23b444d366f2af76f6c89082e5a9aa548c Mon Sep 17 00:00:00 2001 From: Deeptendu Santra Date: Mon, 6 Feb 2023 01:45:27 +0530 Subject: [PATCH 4/6] Tested with 1.8 and 1.9 --- ext/PlutoNotebook.jl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ext/PlutoNotebook.jl b/ext/PlutoNotebook.jl index c16c0912..6c2847d9 100644 --- a/ext/PlutoNotebook.jl +++ b/ext/PlutoNotebook.jl @@ -1,10 +1,9 @@ module PlutoNotebook using Dates -using DemoCards: AbstractDemoCard +using DemoCards: AbstractDemoCard, JULIA_COMPAT, load_config, download_badge, pluto_footer import DemoCards: PlutoDemoCard, save_democards, make_badges, parse isdefined(Base, :get_extension) ? (using PlutoStaticHTML) : (using ..PlutoStaticHTML) -using PlutoStaticHTML function PlutoDemoCard(path::AbstractString)::PlutoDemoCard @@ -125,6 +124,4 @@ end parse(card::PlutoDemoCard) = PlutoStaticHTML.Pluto.frontmatter(card.path) - - end From dce05bf523945c9fe609b217d9526aee8807754e Mon Sep 17 00:00:00 2001 From: Deeptendu Santra Date: Mon, 6 Feb 2023 01:54:38 +0530 Subject: [PATCH 5/6] Add error message when using PlutoCard if PlutoStaticHTML is not loaded --- src/types/pluto.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/types/pluto.jl b/src/types/pluto.jl index 2d3e1436..b424bb71 100644 --- a/src/types/pluto.jl +++ b/src/types/pluto.jl @@ -70,3 +70,6 @@ mutable struct PlutoDemoCard <: AbstractDemoCard hidden::Bool end +function PlutoDemoCard(path::AbstractString)::PlutoDemoCard + throw(ErrorException("You need to load PlutoStaticHTML.jl before using this function.")) +end From a6e09d94b003f51d9a640122e8e7d734f63bbf23 Mon Sep 17 00:00:00 2001 From: Deeptendu Santra Date: Mon, 6 Feb 2023 09:22:36 +0530 Subject: [PATCH 6/6] Remove problem of broken incremental compilation --- src/types/card.jl | 15 ++++++++++++++- src/types/pluto.jl | 8 ++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/types/card.jl b/src/types/card.jl index ab9d1b35..04a5c3bf 100644 --- a/src/types/card.jl +++ b/src/types/card.jl @@ -24,7 +24,20 @@ function democard(path::String)::AbstractDemoCard return MarkdownDemoCard(path) elseif ext in julia_exts if is_pluto_notebook(path) - return PlutoDemoCard(path) + return try + PlutoDemoCard(path) + catch e + if isa(e, MethodError) + # method is not imported from PlutoNotebook + throw( + ErrorException( + "You need to load PlutoStaticHTML.jl for using pluto notebooks", + ), + ) + else + throw(e) + end + end else return JuliaDemoCard(path) end diff --git a/src/types/pluto.jl b/src/types/pluto.jl index b424bb71..eccb27fa 100644 --- a/src/types/pluto.jl +++ b/src/types/pluto.jl @@ -60,16 +60,12 @@ See also: [`PlutoDemoCard`](@ref DemoCards.PlutoDemoCard), [`DemoSection`](@ref """ mutable struct PlutoDemoCard <: AbstractDemoCard path::String - cover::Union{String, Nothing} + cover::Union{String,Nothing} id::String title::String description::String author::String date::DateTime - julia::Union{Nothing, VersionNumber} + julia::Union{Nothing,VersionNumber} hidden::Bool end - -function PlutoDemoCard(path::AbstractString)::PlutoDemoCard - throw(ErrorException("You need to load PlutoStaticHTML.jl before using this function.")) -end