diff --git a/CHANGELOG.md b/CHANGELOG.md index 0063f68..4e54c28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,20 @@ This file contains the changelog for the PlutoExtras package. It follows the [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format. +## [0.7.16] - 2025-09-26 + +### Fixed +- Fixed problems with `ExtendedTableOfContents` with recent PlutoUI versions, also resolving an issue with `hide-heading` icon not appearing next to the corresponding heading in the ToC. +- Fixed styling issue with `BondsTable` in #19 + +### Added +- Added possibility of providing any valid object with a `MIME"text/html"` representation as description of the `@NTBond` macro. +- Added the possibility of simplifying application of `PlutoUI.Experimental.transformed_value` to the fields of an `@NTBond` using the `@tv` decorator (see the example notebook for details). + +### Changed +- Changed the hiding behavior of the `Popout` container so that it stays displayed if the mouse is hovering over its contents even if not popped out + + ## [0.7.15] - 2025-04-22 Changelog was introduced in this version. Only changes w.r.t. version v0.7.14 are listed diff --git a/docs/Project.toml b/docs/Project.toml index 21b45ce..0fd0f0e 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -3,4 +3,4 @@ Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" PlutoExtras = "ed5d0301-4775-4676-b788-cf71e66ff8ed" [compat] -Documenter = "0.27" \ No newline at end of file +Documenter = "1" \ No newline at end of file diff --git a/docs/make.jl b/docs/make.jl index bca89dd..70c08dc 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -5,15 +5,16 @@ using Documenter DocMeta.setdocmeta!(PlutoExtras, :DocTestSetup, :(using PlutoExtras); recursive=true) makedocs(; - modules= Module[], + modules= [PlutoExtras], authors="Alberto Mengali ", - repo="https://github.com/disberd/PlutoExtras.jl/blob/{commit}{path}#{line}", + repo=Remotes.GitHub("disberd", "PlutoExtras.jl"), sitename="PlutoExtras.jl", format=Documenter.HTML(; prettyurls=get(ENV, "CI", "false") == "true", edit_link="master", assets=String[], ), + warnonly = true, pages=[ "index.md", "basic_widgets.md", diff --git a/docs/src/structbond.md b/docs/src/structbond.md index d5dd8f2..ba22f54 100644 --- a/docs/src/structbond.md +++ b/docs/src/structbond.md @@ -5,7 +5,7 @@ The StructBondModule submodule of PlutoExtras defines and exports functionality !!! note The StructBondModule is currently not re-exported by PlutoExtras so it has to be explicitly used with `using PlutoExtras.StructBondModule` -Open the [structbond test notebook static html](https://rawcdn.githack.com/disberd/PlutoExtras.jl/0e3153d29d3b112f93507c042a35b8161a3bb661/html_exports/test_bondstable.jl.html) to see the look of the widgets exported.\ +Open the [structbond module notebook static html](https://raw.githack.com/disberd/PlutoExtras.jl/assets/html/structbondmodule.html) to see the look of the widgets exported.\ Or open the [related notebook](https://github.com/disberd/PlutoExtras.jl/blob/master/test/notebooks/structbondmodule.jl) directy in Pluto to check their functionality in action! !!! note The notebook must be run from the original folder (`test/notebooks`) within the `PlutoExtras` package folder to properly load the PlutoExtras package @@ -37,6 +37,49 @@ The macro simply create a [`StructBond`](@ref) wrapping the desired NamedTuple t ``` +### Transforming the resulting NamedTuple +Since version v0.7.16, it is possible to `PlutoUI.Experimental.transformed_value` to transform the resulting value of the NamedTuple return by the `@NTBond` macro by either providing a third argument to the macro (acting on the full `NamedTuple`) or by using the `@tv` decorator directly when defining the bond for a specific field: + +#### Transforming the full NamedTuple + +When calling the macro with a third argument, this is interpreted as a function that is used to create a bond transformation using `PlutoUI.Experimental.transformed_value`. + +This means that the two expressions below yield the same result: +```julia +@NTBond "WoW" begin + a = ("Description", Slider(1:10)) +end x -> x.a + 2 +``` +and +```julia +PlutoUI.Experimental.transformed_value(x -> x.a + 2, @NTBond "WoW" begin + a = ("Description", Slider(1:10)) +end) +``` + +!!! note + The synthax accepting a function to transformed the resulting NamedTuple also has a convenience shorthand where `_` can be used to represent the original bond value. + + The above example could then also be written as: + ```julia + @NTBond "WoW" begin + a = ("Description", Slider(1:10)) + end _.a + 2 + ``` + +#### Transforming a single field + +For the use directly at field level, it is sufficient to use the `@tv` decorator in place of the bond widget directly, using the following form and as shown in the image below: +```julia + @tv transform_function widget +``` + +![@tv decorator](https://raw.githubusercontent.com/disberd/PlutoExtras.jl/assets/imgs/ntbond_transform_fieldbond.png) + +!!! note + The `@tv` decorator is not a macro actually defined within PlutoExtras, but is directly parsed during the macro expansion of `@NTBond`. + + ## StructBondSelect Sometimes, one wants to create a more complex binding where the number of parameters to control a bond can vary depending on some other variable. The `StructBondSelect` can be of help in some of these cases, by providing a way to select out of a number of arbitrary `StructBonds` (which include `@NTBond`) by using a dropdown to select the one to be displayed and used for generating the `StructBondSelect` widget's output. @@ -52,7 +95,7 @@ The `description` kwarg can be used to customize the text in the widget containe ```@raw html ``` @@ -117,6 +160,7 @@ StructBondModule.@NTBond StructBondModule.@BondsList StructBondModule.popoutwrap StructBondModule.BondTable +StructBondModule.StructBondSelect ``` ### Secondary/Advanced diff --git a/html_exports/test_bondstable.jl.html b/html_exports/test_bondstable.jl.html deleted file mode 100755 index 44ed124..0000000 --- a/html_exports/test_bondstable.jl.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - -
\ No newline at end of file diff --git a/src/extended_toc.js b/src/extended_toc.js index fe5f642..01617e9 100644 --- a/src/extended_toc.js +++ b/src/extended_toc.js @@ -178,7 +178,7 @@ function propagate_state(div, state) { } // Floating UI functionality -const floating_ui = await import('https://esm.sh/@floating-ui/dom') +const floating_ui = await import('https://esm.sh/@floating-ui/dom@1.7.4') // Cell attributes modification function has_cell_attribute(cell_id, attr) { @@ -374,15 +374,8 @@ function repositionTooltip(e) { computePosition(ref, tooltip, { placement: "left", strategy: "fixed", - middleware: [ - offset({ - mainAxis: 0, // No offset along the main axis (left/right) - crossAxis: -scrollTop, // Compensate for vertical scroll - alignmentAxis: 0 // No alignment offset - }) - ] }).then(pos => { - tooltip.style.top = pos.y + "px" + tooltip.style.top = pos.y - scrollTop + "px" }) } @@ -725,7 +718,7 @@ header.addEventListener('click', e => { }) header.addEventListener('mouseenter', (e) => { - const { computePosition, offset } = floating_ui + const { computePosition } = floating_ui // Get the scroll container - this is crucial for proper offset calculation const scrollContainer = document.querySelector('main') || document.documentElement @@ -734,15 +727,8 @@ header.addEventListener('mouseenter', (e) => { computePosition(header, header_container, { placement: "left", strategy: "fixed", - middleware: [ - offset({ - mainAxis: 0, // No offset along the main axis (left/right) - crossAxis: -scrollTop, // Compensate for vertical scroll - alignmentAxis: 0 // No alignment offset - }) - ] }).then(pos => { - header_container.style.top = pos.y + "px" + header_container.style.top = pos.y - scrollTop + "px" // header_container.style.left = pos.x + "px" // header_container.style.right = `calc(1rem + min(80vw, 300px))` }) diff --git a/src/structbond/basics.jl b/src/structbond/basics.jl index 5b1dbc9..a23e133 100644 --- a/src/structbond/basics.jl +++ b/src/structbond/basics.jl @@ -129,12 +129,12 @@ function typehtml(T::Type) ]) """ end - togglereactive_container(inner_bond; description = typedescription(T), title = "This generates a struct of type $(nameof(T))") + collapsible_togglereactive_container(inner_bond; description_html = typedescription(T), title = "This generates a struct of type $(nameof(T))") end ## ToggleReactiveContainer ## # This is a helperfunction to create a togglereactive container around a bond with collapsible content -function togglereactive_container(inner_bond; description, title, classes = String[]) +function collapsible_togglereactive_container(inner_bond; description = "", description_html, title, classes = String[]) ToggleReactiveBond(wrapped() do Child @htl(""" $(Child(inner_bond)) @@ -144,71 +144,9 @@ function togglereactive_container(inner_bond; description, title, classes = Stri const header = trc.firstElementChild const desc = header.querySelector('.description') desc.setAttribute('title', $title) - - // add the collapse button - const collapse_btn = html`` - header.insertAdjacentElement('afterbegin', collapse_btn) - - trc.collapse = () => { - trc.classList.toggle('collapsed') - } - - collapse_btn.onclick = (e) => trc.collapse() - - """) - end; description, classes) + end; description, description_html, classes = String["collapsible", classes...]) end ### Constructor ### diff --git a/src/structbond/css/bondslist.css b/src/structbond/css/bondslist.css index ac79219..c57c68f 100644 --- a/src/structbond/css/bondslist.css +++ b/src/structbond/css/bondslist.css @@ -86,6 +86,6 @@ bondslist-container { align-items: center; row-gap: 5px; } -bondstable-container bondslist-container { +bondtable-container bondslist-container { display: contents; } diff --git a/src/structbond/css/popout.css b/src/structbond/css/popout.css index 9021950..5a3bf73 100644 --- a/src/structbond/css/popout.css +++ b/src/structbond/css/popout.css @@ -13,6 +13,7 @@ popout-contents { padding: 8px; } popout-container.popped > popout-contents, +popout-container.contents-hover > popout-contents, popout-container.header-hover > popout-contents { display: block; position: fixed; diff --git a/src/structbond/css/structbondselect.css b/src/structbond/css/structbondselect.css index 47b54a0..a24c659 100644 --- a/src/structbond/css/structbondselect.css +++ b/src/structbond/css/structbondselect.css @@ -8,7 +8,7 @@ structbond-select > struct-bond.hidden { structbond-select, structbond-select > struct-bond, -structbond-select togglereactive-container { +structbond-select togglereactive-container.collapsible { display: contents; } @@ -20,7 +20,7 @@ structbond-select > .selector .description { color: var(--pluto-output-color, #404040); } -structbond-select >struct-bond>togglereactive-container>togglereactive-header { +structbond-select >struct-bond>togglereactive-container.collapsible>togglereactive-header { display: none; } diff --git a/src/structbond/css/togglereactive.css b/src/structbond/css/togglereactive.css index 43c1572..c1de8a5 100644 --- a/src/structbond/css/togglereactive.css +++ b/src/structbond/css/togglereactive.css @@ -1,4 +1,4 @@ -togglereactive-header > .toggle { +togglereactive-header>.toggle { cursor: pointer; --size: 15px; position: relative; @@ -8,13 +8,15 @@ togglereactive-header > .toggle { background: #c6c6c6; outline: none; border-radius: calc(var(--size)/2); - box-shadow: inset 0 0 calc(var(--size)/8) rgba(0,0,0,.2); + box-shadow: inset 0 0 calc(var(--size)/8) rgba(0, 0, 0, .2); margin: 0 10px; } -togglereactive-header > .toggle:checked { + +togglereactive-header>.toggle:checked { background: #4BD865; } -togglereactive-header > .toggle:before { + +togglereactive-header>.toggle:before { content: ''; position: absolute; width: var(--size); @@ -24,9 +26,72 @@ togglereactive-header > .toggle:before { left: 0px; background: #fff; transform: scale(1.1); - box-shadow: 0 calc(var(--size)/20) calc(var(--size)/8) rgba(0,0,0,.2); + box-shadow: 0 calc(var(--size)/20) calc(var(--size)/8) rgba(0, 0, 0, .2); transition: .1s; } -togglereactive-header > .toggle:checked:before { + +togglereactive-header>.toggle:checked:before { left: var(--size) +} + +togglereactive-container.collapsible field-html { + display: contents; +} + +togglereactive-container.collapsible { + display: grid; + grid-template-columns: 1fr minmax(min(50px, 100%), .4fr); + grid-auto-rows: fit-content(40px); + justify-items: center; + align-items: center; + row-gap: 5px; + /* The flex below is needed in some weird cases where the bond is display flex and the child becomes small. */ + flex: 1; +} + +togglereactive-container.collapsible>togglereactive-header { + grid-column: 1 / -1; + display: flex; +} + +.collapse-btn { + display: none; +} + +togglereactive-container.collapsible>togglereactive-header>.collapse-btn { + --size: 17px; + display: block; + align-self: stretch; + background-size: var(--size) var(--size); + background-repeat: no-repeat; + background-position: center; + width: var(--size); + filter: var(--image-filters); + background-image: url(https://cdn.jsdelivr.net/gh/ionic-team/ionicons@5.5.1/src/svg/chevron-down.svg); + cursor: pointer; +} + +togglereactive-container.collapsible.collapsed>togglereactive-header>.collapse-btn { + background-image: url(https://cdn.jsdelivr.net/gh/ionic-team/ionicons@5.5.1/src/svg/chevron-forward.svg); +} + +togglereactive-container.collapsible>togglereactive-header { + display: flex; + align-items: stretch; + width: 100%; +} + +togglereactive-container.collapsible>togglereactive-header>.description { + text-align: center; + flex-grow: 1; + font-size: 18px; + font-weight: 600; +} + +togglereactive-container.collapsible>togglereactive-header>.toggle { + align-self: center +} + +togglereactive-container.collapsible.collapsed togglereactive-header+* { + display: none !important; } \ No newline at end of file diff --git a/src/structbond/macro.jl b/src/structbond/macro.jl index 9ac4fae..07488a1 100644 --- a/src/structbond/macro.jl +++ b/src/structbond/macro.jl @@ -1,4 +1,49 @@ # Helper Functions # +##### Functions copied from MacroTools.jl #### +walk(x, inner, outer) = outer(x) +walk(x::Expr, inner, outer) = outer(Expr(x.head, map(inner, x.args)...)) +prewalk(f, x) = walk(f(x), x -> prewalk(f, x), identity) +##### End of MacroTools.jl functions #### + +# This traverse the expression and eventually replaces all single underscores with the provided alternative value +function replace_single_underscore(ex::Expr, newval::Symbol) + changed = Ref(false) + newex = prewalk(ex) do x + if x === :_ + changed[] = true + return newval + else + return x + end + end + return newex, changed[] +end + +# This will take an expression and check if it contains single underscores identifiers. If it does, it assumes it has to translate this into an anonymous function with a single argument that will go in place of the underscore +make_function(x) = return x +function make_function(ex::Expr) + Meta.isexpr(ex, :(->)) && return ex + newsym = gensym() + newex, changed = replace_single_underscore(ex, newsym) + if changed + return Expr(:(->), newsym, Expr(:block, newex)) + else + return ex + end +end + +# This function will try parsing the fieldbond expression to eventually deal with `@tv` +process_fieldbond_expression(x) = return x +function process_fieldbond_expression(ex::Expr) + Meta.isexpr(ex, :macrocall) || return ex + args = filter(x -> !(x isa LineNumberNode), ex.args) + macro_name = args[1] + macro_name == Symbol("@tv") || return ex + length(args) == 3 || throw(ArgumentError("The @tv decorator has to be called with two arguments after it.\nThe first must be the transforming function and the second the widget")) + _, func, widget = args + return :($(transformed_value)($(make_function(func)), $widget)) +end + # Generic function for the convenience macros to add methods for the field functions function _add_generic_field(s, block, fnames) if !Meta.isexpr(block, [:block, :let]) @@ -18,6 +63,9 @@ function _add_generic_field(s, block, fnames) # If the value is not already a tuple or vect or expressions, we wrap it in a tuple values = Meta.isexpr(value, [:vect, :tuple]) ? value.args : (value,) for (fname,val) in zip(reverse(fnames), reverse(values)) + if fname == :fieldbond + val = process_fieldbond_expression(val) + end # Push the expression to overload the method push!(out.args, esc(:($Mod.$fname(::Type{$s}, ::Val{$symbol}) = $val))) end @@ -286,7 +334,32 @@ PlutoUI.Experimental.transformed_value(x -> x.a + 2, @NTBond "WoW" begin end) ``` -See also: [`BondTable`](@ref), [`@NTBond`](@ref), [`@BondsList`](@ref), [`Popout`](@ref), [`popoutwrap`](@ref), [`@fielddata`](@ref), [`@fieldhtml`](@ref), [`@typeasfield`](@ref), [`@popoutasfield`](@ref) +!!! note + The synthax accepting a function to transformed the resulting NamedTuple also has a convenience shorthand where `_` can be used to represent the original bond value. + + The above example could then also be written as: + ```julia + @NTBond "WoW" begin + a = ("Description", Slider(1:10)) + end _.a + 2 + ``` + +See also: [`BondTable`](@ref), [`@NTBond`](@ref), [`@BondsList`](@ref), [`Popout`](@ref) + +# Extended Help +## transform single fields +Since version 0.7.16, the `@NTBond` macro supports a convenience decorator to transform a single field. This is done by using the `@tv` decorator, which is a shorthand for `PlutoUI.Experimental.transformed_value`. + +`@tv` is not a macro actually defined within PlutoExtras, but is directly parsed during the macro expansion of `@NTBond`. See the image below for an example of how to use it: + +![@tv decorator](https://raw.githubusercontent.com/disberd/PlutoExtras.jl/assets/imgs/ntbond_transform_fieldbond.png) + +## Markdown math in description +Since version 0.7.16, the `@NTBond` macro supports providing a description as anything that has a valid `MIME"text/html"` representation. This includes markdown with math inside! + +See the image below for an example of how to use it: + +![@NTBond with math (using markdown) in description](https://raw.githubusercontent.com/disberd/PlutoExtras.jl/assets/imgs/ntbond_markdown_description.png) """ macro NTBond(desc, args...) return _NTBond(desc, args...) @@ -294,6 +367,7 @@ end function _NTBond(desc, block) Meta.isexpr(block, [:let, :block]) || error("You can only give `let` or `begin` blocks to the `@NTBond` macro") + desc = esc(desc) # We will return a let block at the end anyhow to avoid method redefinitino errors in Pluto. We already create the two blocks composing the let bindings, block = if block.head == :let block.args @@ -314,14 +388,24 @@ function _NTBond(desc, block) end T = NamedTuple{Tuple(fields)} out = _add_generic_field(T, block, [:fielddescription, :fieldbond]) + # We try to extract the string and html description from the first argument + push!(out.args, :((string_desc, html_desc) = if $desc isa AbstractString + $desc, $desc # We use the string for also for HTML + elseif $desc isa Tuple{AbstractString, Any} + $desc # we already have a tuple so we simply slit the two elements + else + "No String Description Provided", $desc # Fallback default for the string name + end)) + # We push an expression that adds a method for the fielddescription + push!(out.args, :($(@__MODULE__).typedescription(::Type{$T}) = html_desc)) # We add the generation of the StructBond - push!(out.args, :($(StructBond)($T;description = $desc))) + push!(out.args, :($(StructBond)($T;description = string_desc))) Expr(:let, bindings, out) end function _NTBond(desc, block, tv) expr = _NTBond(desc, block) - return :($(transformed_value)($(esc(tv)), $expr)) + return :($(transformed_value)($(esc(make_function(tv))), $expr)) end diff --git a/src/structbond/main_definitions.jl b/src/structbond/main_definitions.jl index fcf7d03..022ccfc 100644 --- a/src/structbond/main_definitions.jl +++ b/src/structbond/main_definitions.jl @@ -25,10 +25,10 @@ See also: [`BondTable`](@ref), [`@NTBond`](@ref), [`@BondsList`](@ref), """ Base.@kwdef struct StructBond{T} widget::Any - description::Any + description::String secret_key::String=String(rand('a':'z', 10)) end -StructBond(::Type{T}; description = typedescription(T)) where T = StructBond{T}(;widget = typehtml(T), description) +StructBond(::Type{T}; description = string(nameof(T))) where T = StructBond{T}(;widget = typehtml(T), description) ## structbondtype ## structbondtype(::StructBond{T}) where T = T @@ -36,36 +36,6 @@ structbondtype(::Type{StructBond{T}}) where T = T ## Show - StructBond ## -# This does not seem used, leaving here for the moment -_basics_script = ScriptContent(""" - const parent = currentScript.parentElement - const widget = currentScript.previousElementSibling - - // Overwrite the description - const desc = widget.querySelector('.description') - desc.innerHTML = - - // Set-Get bond - - const set_input_value = setBoundElementValueLikePluto - const get_input_value = getBoundElementValueLikePluto - - Object.defineProperty(parent, 'value', { - get: () => get_input_value(widget), - set: (newval) => { - set_input_value(widget, newval) - }, - configurable: true, - }); - - const old_oninput = widget.oninput ?? function(e) {} - widget.oninput = (e) => { - old_oninput(e) - e.stopPropagation() - parent.dispatchEvent(new CustomEvent('input')) - } -""") - # Basic script part used for the show method _show(t::StructBond{T}) where T = @htl(""" @@ -77,7 +47,6 @@ _show(t::StructBond{T}) where T = @htl(""" // Overwrite the description const desc = widget.querySelector('.description') - desc.innerHTML = $(t.description) // Set-Get bond @@ -338,7 +307,7 @@ _show_popout(p::Popout) = wrapped() do Child """) - show(io, mime, togglereactive_container(inner_bond; description = sb.description, title = "Use the selector to choose which StructBond to display and use.", classes = ["structbond-select"])) + show(io, mime, collapsible_togglereactive_container(inner_bond; description = sb.description, description_html = sb.description_html, title = "Use the selector to choose which StructBond to display and use.", classes = ["structbond-select"])) end Bonds.initial_value(sbc::StructBondSelect) = Bonds.initial_value(sbc.els[sbc.default_idx]) diff --git a/src/structbond/toggle_reactive.jl b/src/structbond/toggle_reactive.jl index f9dec5b..70f4a34 100644 --- a/src/structbond/toggle_reactive.jl +++ b/src/structbond/toggle_reactive.jl @@ -4,8 +4,9 @@ Base.@kwdef struct ToggleReactiveBond description::String secret_key::String=String(rand('a':'z', 10)) classes::Vector{String}=String[] + description_html = description end -ToggleReactiveBond(element; description = "", classes = String[]) = ToggleReactiveBond(;element, description, classes) +ToggleReactiveBond(element; description = "", classes = String[], description_html = description) = ToggleReactiveBond(;element, description, classes, description_html) # AbstractPlutoDingetjes Methods # function Bonds.initial_value(r::ToggleReactiveBond) @@ -25,7 +26,8 @@ end Base.show(io::IO, mime::MIME"text/html", r::ToggleReactiveBond) = show(io, mime, @htl(""" - $(r.description) + + $(r.description_html) $(r.element) @@ -33,6 +35,13 @@ Base.show(io::IO, mime::MIME"text/html", r::ToggleReactiveBond) = show(io, mime, const parent = currentScript.parentElement const el = currentScript.previousElementSibling const toggle = parent.querySelector('togglereactive-header .toggle') + const collapse_btn = parent.querySelector('togglereactive-header .collapse-btn') + + parent.collapse = () => { + parent.classList.toggle('collapsed') + } + + collapse_btn.onclick = (e) => parent.collapse() const set_input_value = setBoundElementValueLikePluto const get_input_value = getBoundElementValueLikePluto diff --git a/test/notebooks/structbondmodule backup 1.jl b/test/notebooks/structbondmodule backup 1.jl deleted file mode 100644 index 3247da9..0000000 --- a/test/notebooks/structbondmodule backup 1.jl +++ /dev/null @@ -1,490 +0,0 @@ -### A Pluto.jl notebook ### -# v0.20.5 - -#> custom_attrs = ["hide-enabled"] - -using Markdown -using InteractiveUtils - -# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). -macro bind(def, element) - #! format: off - return quote - local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end - local el = $(esc(element)) - global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) - el - end - #! format: on -end - -# ╔═╡ 8db82e94-5c81-4c52-9228-7e22395fb68f -begin - using PlutoDevMacros -end - -# ╔═╡ 949ac1ef-c502-4e28-81ff-f99b0d19aa03 -@frompackage "../.." begin - using ^.StructBondModule - using ^: ExtendedTableOfContents, Editable - using >.HypertextLiteral - using >.PlutoUI -end - -# ╔═╡ 9d4455af-96f1-46d7-a4f3-434495b11c8a -md""" -# Packages -""" - -# ╔═╡ 707175a9-d356-43cf-8038-620ebc401c93 -ExtendedTableOfContents() - -# ╔═╡ cbfc6eec-8991-4a9c-ada0-295c8052854d -# html""" -# -# """ - -# ╔═╡ 4843983c-df64-4b94-8634-7a10d9423a70 -md""" -# StructBond -""" - -# ╔═╡ a8995224-83c6-4f82-b5a5-87a6f86fc7a0 -md""" -Generating automatic widgets for custom structs is quite straightforward with the aid of the `@fielddata` macro and the `StructBond` type. - -The top-left arrow can be used to show-hide the field elements (useful inside a `BondTable`, shown below), while the green toggle on the top-right can be used to disable temporarily the synch between the JS widgets and the bond values in Pluto. -""" - -# ╔═╡ 9e3601f5-efc2-44e9-83d8-5b65ce7e9ccf -begin -""" - struct ASD -""" -Base.@kwdef struct ASD - a::Int - b::Int - c::String - "This field is _special_" - d::String - e::Int -end -@typeasfield String = TextField() # String fields with no struct-specific default will use this -@fielddata ASD begin - a = (md"Markdown description, including ``LaTeX``", Slider(1:10)) - b = (@htl("Field with HTML description"), Scrubbable(1:10)) - c = ("Normal String Description", TextField()) - # d has no ASD-specific custom bond, so it will use the field docstring as description and the default String widget as widget - e = Slider(20:25) # No description, defaults to the fieldname as no docstring is present -end -asd_bond = @bind asd StructBond(ASD; description = "Custom Description") -end - -# ╔═╡ cdc0a7ad-a3ac-4270-b707-35b1939da276 -asd - -# ╔═╡ fe891b4e-f440-4823-b43b-72572f6a6c12 -md""" -## Default Type Widgets -""" - -# ╔═╡ 86a80228-f495-43e8-b1d4-c93b7b52c8d8 -begin - @kwdef struct MAH - a::Int - end - @kwdef struct BOH - mah::MAH - end - - # This will make the default widget for an Int a Slider - @typeasfield Int = Slider(1:10) - # This will make the default widget for fields of type ASD a popout that wraps a StructBond{ASD} - @popoutasfield MAH - - @bind boh StructBond(BOH) -end - -# ╔═╡ 2358f686-1950-40f9-9d5c-dac2d98f4c24 -boh - -# ╔═╡ 49516374-f625-4a84-ac5c-f92497d45025 -md""" -# @NTBond -""" - -# ╔═╡ 8cc53cd2-9114-4067-ab0b-37fd8cd79240 -md""" -Sometimes custom structs are not needed and it would be useful to just use the same nice bond structure of `StructBond` to simply create arbitrary NamedTuples. - -This is possible with the convenience macro `@NTBond` which can be called as shown below to create a nice display for an interactive bond creating an arbitrary NamedTuple. - -The macro simply create a `StructBond` wrapping the desired NamedTuple type. -""" - -# ╔═╡ 0db51d39-7c05-4e00-b951-7fe776a8e0f9 -nt_bond = @bind nt @NTBond "My Fancy NTuple" begin - a = ("Description", Slider(1:10)) - b = (md"**Bold** field", Slider(1:10)) - c = Slider(1:10) # No description, defaults to the name of the field -end - -# ╔═╡ e2b79a58-e66e-4d40-8673-418823753b38 -nt - -# ╔═╡ 9d23382c-cf35-4b20-a46c-0f4e2de17fc7 -md""" -# @BondsList -""" - -# ╔═╡ 959acb40-1fd6-43f5-a1a6-73a6ceaae1d7 -md""" -In some cases, one does not want to have a single bond wrapping either a Structure or a NamedTuple because single independent bonds are more convenient. - -`@BondsList` is a convenience macro to create an object of type `BondsList` which simply allow to add a description to separate bonds and group them all together in a table-like format equivalent to those of `StructBond`. - -!!! note - Unlike `StructBond`, a BondsList is already composed of bond created with `@bind` and it just groups them up with a description. The output of `@BondsList` is not supposed to be bound to a variable using `@bind`.\ - The bonds grouped in a BondsList still act and update independently from one another. - -See the example below for understanding the synthax. The header of a BondsList is shown in an orange background to easily differentiate it from `StructBond`. -""" - -# ╔═╡ 4d611425-c8e3-4bc3-912b-8bc0465363bc -bl = @BondsList "My Group of Bonds" let tv = PlutoUI.Experimental.transformed_value - # We use transformed_value to translate GHz to Hz in the bound variable `freq` - "Frequency [GHz]" = @bind freq tv(x -> x * 1e9, Editable(20; suffix = " GHz")) - md"Altitude ``h`` [m]" = @bind alt Scrubbable(100:10:200) -end - -# ╔═╡ a5490a6b-dc11-42b7-87e0-d38870fc55e4 -freq - -# ╔═╡ 705e30fe-77a3-4b06-8b99-1807290edffb -alt - -# ╔═╡ 2ee7f26d-f383-4e7e-a69a-8fb72717467c -md""" -# Popout -""" - -# ╔═╡ 79beba88-932f-4147-b3a0-d821ef1bc1e2 -md""" -The structures above can also be used nested within one another. To facilitate accessing nested structures, one can use the `Popout` type. - -In its simple form, you can give an instance of a StructBond, a bond wrapping a StructBond or a BondsList as input to Popout to create a table that is hidden behind a popup window. -If an instance present, but you want a custom type for which you have defined custom bonds and descriptions with `@fielddata` to appear as popout, you can use the function `popoutwrap(TYPE)` to generate a small icon which hides a popup containing the `StructBond` of the provided type `TYPE`. - -The StructBond table appears on hover upon the icon, can be made fixed by clicking on the icon and can then be moved around or resized. -A double click on the header of the popout hides it again: -""" - -# ╔═╡ 63d6c2df-a411-407c-af11-4f5d09fbb322 -begin -Base.@kwdef struct LOL - a::Int - b::Int -end -@fielddata LOL begin - a = (md"Wonder!", Slider(1:10)) - b = (@htl("Field B"), Scrubbable(1:10)) -end -end - -# ╔═╡ 633029af-8cac-426e-b35c-c9fb3938b784 -@bind lol_pop popoutwrap(LOL) - -# ╔═╡ 065bad73-5fa8-4496-ba33-9e66940b5806 -lol_pop - -# ╔═╡ 2073f11e-8196-4ebc-922f-5fa589e91797 -md""" -The ability to also wrap pre-existing bonds around StructBonds is convenient for organizing the various bonds one have in a `BondsList` or `BondTable` - -As an example, one can create a `BondsList` containing the two `StructBond` bonds generated at the beginning of this notebook with the follwing code. -""" - -# ╔═╡ 811cf78b-e870-45bb-9173-89a3b3d495f5 -blc = @BondsList "Popout Container" begin - "Structure ASD" = Popout(asd_bond) - "NamedTuple" = Popout(nt_bond) -end - -# ╔═╡ e7d67662-77b3-482a-b032-8db4afbc01a6 -asd - -# ╔═╡ 996b4085-114c-48f4-9f90-8e637f29c06a -nt - -# ╔═╡ 3a066bf4-3466-469e-90d0-6b14be3ed8d5 -md""" -# BondTable -""" - -# ╔═╡ 3213d977-7b65-43b0-a881-10fcc2523f14 -md""" -The final convenience structure provided by this module is the `BondTable`. It can be created to group a list of bonds in a floating table that stays on the left side of the notebook (similar to the TableOfContents of PlutoUI) and can be moved around and resized or hidden for convenience. - -The BondTable is intended to be used either with bonds containing `StructBond` or with `BondsList`. Future types with similar structure will also be added. - -Here is an example of a bondtable containing all the examples of this notebook. -""" - -# ╔═╡ 903fee67-6b23-41dc-a03d-f1040b696be6 -BondTable([ - asd_bond, - nt_bond, - bl, - blc -]; description = "My Bonds") - -# ╔═╡ 08d711c0-e2cc-4444-94ca-0c4c3cfe901f -nt - -# ╔═╡ 03e9d75e-e6c9-4199-933b-2be306daf978 -asd - -# ╔═╡ 26d11600-2827-4e08-9195-109c8a8bddc3 -freq - -# ╔═╡ be2a7820-e194-4410-b00d-a9332b234ad6 -alt - -# ╔═╡ 00000000-0000-0000-0000-000000000001 -PLUTO_PROJECT_TOML_CONTENTS = """ -[deps] -PlutoDevMacros = "a0499f29-c39b-4c5c-807c-88074221b949" - -[compat] -PlutoDevMacros = "~0.7.0" -""" - -# ╔═╡ 00000000-0000-0000-0000-000000000002 -PLUTO_MANIFEST_TOML_CONTENTS = """ -# This file is machine-generated - editing it directly is not advised - -julia_version = "1.11.4" -manifest_format = "2.0" -project_hash = "9088728c15a23247dcd792960c847dd5035deb53" - -[[deps.AbstractPlutoDingetjes]] -deps = ["Pkg"] -git-tree-sha1 = "0f748c81756f2e5e6854298f11ad8b2dfae6911a" -uuid = "6e696c72-6542-2067-7265-42206c756150" -version = "1.3.0" - -[[deps.ArgTools]] -uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" -version = "1.1.2" - -[[deps.Artifacts]] -uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" -version = "1.11.0" - -[[deps.Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" -version = "1.11.0" - -[[deps.Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" -version = "1.11.0" - -[[deps.DocStringExtensions]] -deps = ["LibGit2"] -git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.9.3" - -[[deps.Downloads]] -deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] -uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" -version = "1.6.0" - -[[deps.FileWatching]] -uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" -version = "1.11.0" - -[[deps.HypertextLiteral]] -deps = ["Tricks"] -git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" -uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" -version = "0.9.5" - -[[deps.InteractiveUtils]] -deps = ["Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" -version = "1.11.0" - -[[deps.LibCURL]] -deps = ["LibCURL_jll", "MozillaCACerts_jll"] -uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" -version = "0.6.4" - -[[deps.LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] -uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.6.0+0" - -[[deps.LibGit2]] -deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" -version = "1.11.0" - -[[deps.LibGit2_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] -uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.7.2+0" - -[[deps.LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "MbedTLS_jll"] -uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.0+1" - -[[deps.Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" -version = "1.11.0" - -[[deps.Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" -version = "1.11.0" - -[[deps.MacroTools]] -deps = ["Markdown", "Random"] -git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.13" - -[[deps.Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" -version = "1.11.0" - -[[deps.MbedTLS_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.6+0" - -[[deps.MozillaCACerts_jll]] -uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2023.12.12" - -[[deps.NetworkOptions]] -uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" -version = "1.2.0" - -[[deps.Pkg]] -deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.11.0" - - [deps.Pkg.extensions] - REPLExt = "REPL" - - [deps.Pkg.weakdeps] - REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" - -[[deps.PlutoDevMacros]] -deps = ["AbstractPlutoDingetjes", "DocStringExtensions", "HypertextLiteral", "InteractiveUtils", "MacroTools", "Markdown", "Pkg", "Random", "TOML"] -git-tree-sha1 = "2944f76ac8c11c913a620da0a6b035e2fadf94c1" -uuid = "a0499f29-c39b-4c5c-807c-88074221b949" -version = "0.7.2" - -[[deps.Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" -version = "1.11.0" - -[[deps.Random]] -deps = ["SHA"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -version = "1.11.0" - -[[deps.SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" -version = "0.7.0" - -[[deps.TOML]] -deps = ["Dates"] -uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" -version = "1.0.3" - -[[deps.Tar]] -deps = ["ArgTools", "SHA"] -uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" -version = "1.10.0" - -[[deps.Tricks]] -git-tree-sha1 = "eae1bb484cd63b36999ee58be2de6c178105112f" -uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" -version = "0.1.8" - -[[deps.UUIDs]] -deps = ["Random", "SHA"] -uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" -version = "1.11.0" - -[[deps.Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" -version = "1.11.0" - -[[deps.Zlib_jll]] -deps = ["Libdl"] -uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.2.13+1" - -[[deps.nghttp2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.59.0+0" - -[[deps.p7zip_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.4.0+2" -""" - -# ╔═╡ Cell order: -# ╟─9d4455af-96f1-46d7-a4f3-434495b11c8a -# ╠═8db82e94-5c81-4c52-9228-7e22395fb68f -# ╠═949ac1ef-c502-4e28-81ff-f99b0d19aa03 -# ╠═707175a9-d356-43cf-8038-620ebc401c93 -# ╠═cbfc6eec-8991-4a9c-ada0-295c8052854d -# ╟─4843983c-df64-4b94-8634-7a10d9423a70 -# ╟─a8995224-83c6-4f82-b5a5-87a6f86fc7a0 -# ╠═9e3601f5-efc2-44e9-83d8-5b65ce7e9ccf -# ╠═cdc0a7ad-a3ac-4270-b707-35b1939da276 -# ╟─fe891b4e-f440-4823-b43b-72572f6a6c12 -# ╠═86a80228-f495-43e8-b1d4-c93b7b52c8d8 -# ╠═2358f686-1950-40f9-9d5c-dac2d98f4c24 -# ╟─49516374-f625-4a84-ac5c-f92497d45025 -# ╟─8cc53cd2-9114-4067-ab0b-37fd8cd79240 -# ╠═0db51d39-7c05-4e00-b951-7fe776a8e0f9 -# ╠═e2b79a58-e66e-4d40-8673-418823753b38 -# ╟─9d23382c-cf35-4b20-a46c-0f4e2de17fc7 -# ╟─959acb40-1fd6-43f5-a1a6-73a6ceaae1d7 -# ╠═4d611425-c8e3-4bc3-912b-8bc0465363bc -# ╠═a5490a6b-dc11-42b7-87e0-d38870fc55e4 -# ╠═705e30fe-77a3-4b06-8b99-1807290edffb -# ╟─2ee7f26d-f383-4e7e-a69a-8fb72717467c -# ╟─79beba88-932f-4147-b3a0-d821ef1bc1e2 -# ╠═63d6c2df-a411-407c-af11-4f5d09fbb322 -# ╠═633029af-8cac-426e-b35c-c9fb3938b784 -# ╠═065bad73-5fa8-4496-ba33-9e66940b5806 -# ╟─2073f11e-8196-4ebc-922f-5fa589e91797 -# ╠═811cf78b-e870-45bb-9173-89a3b3d495f5 -# ╠═e7d67662-77b3-482a-b032-8db4afbc01a6 -# ╠═996b4085-114c-48f4-9f90-8e637f29c06a -# ╟─3a066bf4-3466-469e-90d0-6b14be3ed8d5 -# ╟─3213d977-7b65-43b0-a881-10fcc2523f14 -# ╠═903fee67-6b23-41dc-a03d-f1040b696be6 -# ╠═08d711c0-e2cc-4444-94ca-0c4c3cfe901f -# ╠═03e9d75e-e6c9-4199-933b-2be306daf978 -# ╠═26d11600-2827-4e08-9195-109c8a8bddc3 -# ╠═be2a7820-e194-4410-b00d-a9332b234ad6 -# ╟─00000000-0000-0000-0000-000000000001 -# ╟─00000000-0000-0000-0000-000000000002 diff --git a/test/notebooks/structbondmodule.jl b/test/notebooks/structbondmodule.jl index 1a7eaec..1972fad 100644 --- a/test/notebooks/structbondmodule.jl +++ b/test/notebooks/structbondmodule.jl @@ -1,5 +1,5 @@ ### A Pluto.jl notebook ### -# v0.20.5 +# v0.20.17 #> custom_attrs = ["hide-enabled"] @@ -21,6 +21,7 @@ end # ╔═╡ 8db82e94-5c81-4c52-9228-7e22395fb68f begin using PlutoDevMacros + using LaTeXStrings end # ╔═╡ 949ac1ef-c502-4e28-81ff-f99b0d19aa03 @@ -147,14 +148,87 @@ md""" """ # ╔═╡ 7855826e-ccaa-4c27-a060-f5ceb927bbe8 -@bind transformed_value_example @NTBond "Transformed!" begin +@bind transformed_value_example @NTBond md"Transformed!" begin a = Slider(1:10) b = Slider(1:10) -end nt -> nt.a + nt.b +end _.a + _.b # This function is replaced within the macro to be `nt -> nt.a + nt.b`, which could have also been provided as anonymous function directly # ╔═╡ 1d5573ee-872e-4dfb-a785-1ac9e836ad98 transformed_value_example +# ╔═╡ 5bb22f07-fbea-44ab-9783-9ca16e0da11e +md""" +### Transform only a few fields +""" + +# ╔═╡ 134d6033-2f08-4f49-9829-6a023b368a70 +md""" +A similar approach can also be achieved on a field by field basis by using the `@tv` decorator (which is not a macro per-se but is directly processed during the macro expansion of `@NTBond`). + +`@tv` is a shorthand for transformed_value and it expects two arguments after it, the first being the function to process the value returned by the widget, and the second being the widget itself. + +This can be used to be a bit less verbose when one is interested in only transforming one of many fields as below: +""" + +# ╔═╡ 5438e9e7-c0f7-4523-8682-ffb822359d50 +simple_slider = Slider(1:10); + +# ╔═╡ 02e58012-5af6-4b91-a9a4-09c9dc038f11 +@bind transform_single_field @NTBond "Field Level Transformed Value" begin + a = ("Angle [°]", @tv deg2rad Slider(0:90; default = 60, show_value=true)) # This transforms the angle into radians + b = @tv x -> x + 3 simple_slider # You can either use the full anonymous function synthax, or the convenience form where _ is automatically interpreted as the variable of the anonymous function like below + c = @tv _^2 Slider(1:10; default = 3) # First argument transformed to the anon func x -> x^2 + d = Slider(1:10) +end + +# ╔═╡ e102613f-244c-4b49-9837-535bf047a14a +transform_single_field + +# ╔═╡ 8eb18c7f-bb4d-4cdc-9e30-d561f9099800 +md""" +## Markdown math in description +""" + +# ╔═╡ 052b8bbd-acca-4c00-a5de-0c717ed068e3 +md""" +The description of an `@NTBond` can now be provided as anything that has a valid `MIME"text/html"` representation. This includes markdown with math inside! +""" + +# ╔═╡ bb04ac12-20a0-467a-af1a-c298301e4838 +markdown_function = nt -> atan(nt.x, nt.y) + 3 + +# ╔═╡ 36faf18c-11c3-4012-a996-55c7cdae71a8 +math_ntbond = @bind atanval @NTBond md"This is math!: ``\;atan(x,y) + 3``" begin + x = (md"``x``", Slider(1:10; show_value=true)) + y = (md"``y``", Slider(1:10; show_value=true)) +end markdown_function # We can also directly use functions in the caller scope to transform the value + +# ╔═╡ 27977526-75dc-44c3-9976-c22e8cbd94da +atanval + +# ╔═╡ da3ae348-083d-4a7d-aabd-d0bc25b3ca17 +md""" +## Custom HTML description +""" + +# ╔═╡ 3c2c257e-bbee-4a04-b3ba-68f2382fce87 +@NTBond(md"asd", begin a = Slider(1:10) end).description + +# ╔═╡ c43c8a65-3f94-45f9-b633-71cade09b666 +md""" +When providing a description that is not a string, by default the description field inside of the resulting `StructBond` is set to `"No String Description Provided"`. + +If for some reason one wants to customize the string description, a tuple with `(string_description, html_description)` can be provided +""" + +# ╔═╡ cf807cb3-5d75-4040-bfd1-05fe70d26e89 +tuple_description_ntbond = @NTBond ("Plain description", html"HTML Description") begin + a = Slider(1:10) +end + +# ╔═╡ 564968fe-0a68-48bc-9e11-c7732e2bae04 +tuple_description_ntbond.description + # ╔═╡ f65b3231-f2b2-45dc-b72e-1ad3107083fc md""" # StructBondSelect @@ -311,19 +385,21 @@ alt # ╔═╡ 00000000-0000-0000-0000-000000000001 PLUTO_PROJECT_TOML_CONTENTS = """ [deps] +LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" PlutoDevMacros = "a0499f29-c39b-4c5c-807c-88074221b949" [compat] -PlutoDevMacros = "~0.9.0" +LaTeXStrings = "~1.4.0" +PlutoDevMacros = "~0.9.1" """ # ╔═╡ 00000000-0000-0000-0000-000000000002 PLUTO_MANIFEST_TOML_CONTENTS = """ # This file is machine-generated - editing it directly is not advised -julia_version = "1.11.4" +julia_version = "1.12.0-rc2" manifest_format = "2.0" -project_hash = "9c51cf46a1e177639a0c248b9cdccbfd7b4d05d7" +project_hash = "11800ebf5b54db0d4fffa3305d79ef89c399c1f8" [[deps.ArgTools]] uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" @@ -339,9 +415,9 @@ version = "1.11.0" [[deps.CodeTracking]] deps = ["InteractiveUtils", "UUIDs"] -git-tree-sha1 = "062c5e1a5bf6ada13db96a4ae4749a4c2234f521" +git-tree-sha1 = "980f01d6d3283b3dbdfd7ed89405f96b7256ad57" uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2" -version = "1.3.9" +version = "2.0.1" [[deps.Dates]] deps = ["Printf"] @@ -364,9 +440,19 @@ version = "1.11.0" [[deps.JuliaInterpreter]] deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"] -git-tree-sha1 = "872cd273cb995ed873c58f196659e32f11f31543" +git-tree-sha1 = "d8337622fe53c05d16f031df24daf0270e53bc64" uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" -version = "0.9.44" +version = "0.10.5" + +[[deps.JuliaSyntaxHighlighting]] +deps = ["StyledStrings"] +uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011" +version = "1.12.0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.4.0" [[deps.LibCURL]] deps = ["LibCURL_jll", "MozillaCACerts_jll"] @@ -374,24 +460,24 @@ uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" version = "0.6.4" [[deps.LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.6.0+0" +version = "8.11.1+1" [[deps.LibGit2]] -deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" version = "1.11.0" [[deps.LibGit2_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.7.2+0" +version = "1.9.0+0" [[deps.LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +deps = ["Artifacts", "Libdl", "OpenSSL_jll"] uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.0+1" +version = "1.11.3+1" [[deps.Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" @@ -407,27 +493,27 @@ uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" version = "0.5.16" [[deps.Markdown]] -deps = ["Base64"] +deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" version = "1.11.0" -[[deps.MbedTLS_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.6+0" - [[deps.MozillaCACerts_jll]] uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2023.12.12" +version = "2025.5.20" [[deps.NetworkOptions]] uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" -version = "1.2.0" +version = "1.3.0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.5.1+0" [[deps.Pkg]] deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.11.0" +version = "1.12.0" [deps.Pkg.extensions] REPLExt = "REPL" @@ -437,9 +523,9 @@ version = "1.11.0" [[deps.PlutoDevMacros]] deps = ["JuliaInterpreter", "Logging", "MacroTools", "Pkg", "TOML"] -git-tree-sha1 = "72f65885168722413c7b9a9debc504c7e7df7709" +git-tree-sha1 = "1cb861c9295d79dc6e23170d4b33bce013f69643" uuid = "a0499f29-c39b-4c5c-807c-88074221b949" -version = "0.9.0" +version = "0.9.1" [[deps.Printf]] deps = ["Unicode"] @@ -455,6 +541,10 @@ version = "1.11.0" uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" version = "0.7.0" +[[deps.StyledStrings]] +uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" +version = "1.11.0" + [[deps.TOML]] deps = ["Dates"] uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" @@ -477,17 +567,17 @@ version = "1.11.0" [[deps.Zlib_jll]] deps = ["Libdl"] uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.2.13+1" +version = "1.3.1+2" [[deps.nghttp2_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.59.0+0" +version = "1.64.0+1" [[deps.p7zip_jll]] deps = ["Artifacts", "Libdl"] uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.4.0+2" +version = "17.5.0+2" """ # ╔═╡ Cell order: @@ -511,6 +601,21 @@ version = "17.4.0+2" # ╟─4cb128aa-7ad8-4d17-bced-36845703e6a8 # ╠═7855826e-ccaa-4c27-a060-f5ceb927bbe8 # ╠═1d5573ee-872e-4dfb-a785-1ac9e836ad98 +# ╟─5bb22f07-fbea-44ab-9783-9ca16e0da11e +# ╟─134d6033-2f08-4f49-9829-6a023b368a70 +# ╠═5438e9e7-c0f7-4523-8682-ffb822359d50 +# ╠═02e58012-5af6-4b91-a9a4-09c9dc038f11 +# ╠═e102613f-244c-4b49-9837-535bf047a14a +# ╟─8eb18c7f-bb4d-4cdc-9e30-d561f9099800 +# ╟─052b8bbd-acca-4c00-a5de-0c717ed068e3 +# ╠═bb04ac12-20a0-467a-af1a-c298301e4838 +# ╠═36faf18c-11c3-4012-a996-55c7cdae71a8 +# ╠═27977526-75dc-44c3-9976-c22e8cbd94da +# ╟─da3ae348-083d-4a7d-aabd-d0bc25b3ca17 +# ╠═3c2c257e-bbee-4a04-b3ba-68f2382fce87 +# ╟─c43c8a65-3f94-45f9-b633-71cade09b666 +# ╠═cf807cb3-5d75-4040-bfd1-05fe70d26e89 +# ╠═564968fe-0a68-48bc-9e11-c7732e2bae04 # ╟─f65b3231-f2b2-45dc-b72e-1ad3107083fc # ╟─67c0860b-b4c1-412d-870a-a4ce4987465e # ╠═bd5ec086-5156-4e7c-a70b-5ca9f089bb49 diff --git a/test/structbond.jl b/test/structbond.jl index 86eda79..ac7de91 100644 --- a/test/structbond.jl +++ b/test/structbond.jl @@ -2,7 +2,7 @@ using PlutoExtras using Markdown using PlutoExtras.StructBondModule - using PlutoExtras.StructBondModule: structbondtype, popoutwrap, fieldbond, NotDefined, typeasfield, collect_reinterpret! + using PlutoExtras.StructBondModule: structbondtype, popoutwrap, fieldbond,NotDefined, typeasfield, collect_reinterpret! import PlutoExtras.AbstractPlutoDingetjes.Bonds using Test @@ -128,4 +128,11 @@ end @test eval_in_nb(sn, :alt) == 150 @test eval_in_nb(sn, :freq) == 2e10 SessionActions.shutdown(ss, nb) +end + +@testitem "StructBondModule misc coverage" begin + ex = :(f(x)) + @test StructBondModule.make_function(ex) == ex + + @test StructBondModule.process_fieldbond_expression(:a) == :a end \ No newline at end of file