From 8965a72f0060987277580bb5e13b312aa7333c5e Mon Sep 17 00:00:00 2001 From: Venkateshprasad <32921645+ven-k@users.noreply.github.com> Date: Sat, 4 Nov 2023 11:01:39 +0530 Subject: [PATCH 1/2] refactor: improvements to how `@icon` is parsed - allows only one `@icon` per model; throws an error ow. - Although wrapping inlined `@icon` within `begin...end` is still valid; it is no longer required; aka SVGs with just quotes are allowed. - Validity of SVG-string is verified too. --- src/systems/model_parsing.jl | 19 ++++++++----------- test/icons/resistor.svg | 2 +- test/model_parsing.jl | 10 +++------- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/systems/model_parsing.jl b/src/systems/model_parsing.jl index 3ee6c2800f..650f44e9e2 100644 --- a/src/systems/model_parsing.jl +++ b/src/systems/model_parsing.jl @@ -259,7 +259,8 @@ function parse_model!(exprs, comps, ext, eqs, icon, vs, ps, sps, elseif mname == Symbol("@equations") parse_equations!(exprs, eqs, dict, body) elseif mname == Symbol("@icon") - parse_icon!(icon, dict, mod, body) + isassigned(icon) && error("This model has more than one icon.") + parse_icon!(icon, dict, body) else error("$mname is not handled.") end @@ -471,7 +472,7 @@ function parse_equations!(exprs, eqs, dict, body) dict[:equations] = readable_code.(eqs) end -function parse_icon!(icon, dict, mod, body::String) +function parse_icon!(icon, dict, body::String) icon_dir = get(ENV, "MTK_ICONS_DIR", joinpath(DEPOT_PATH[1], "mtk_icons")) dict[:icon] = icon[] = if isfile(body) URI("file:///" * abspath(body)) @@ -483,17 +484,13 @@ function parse_icon!(icon, dict, mod, body::String) false end URI(body) + elseif (_body = lstrip(body); startswith(_body, r"<\?xml| get_var(mod, _icon) - ::String => _icon - Expr(:call, read, a...) => eval(_icon) - _ => error("$_icon isn't a valid icon") - end +function parse_icon!(icon, dict, body::Expr) + parse_icon!(icon, dict, eval(body)) end diff --git a/test/icons/resistor.svg b/test/icons/resistor.svg index 5f8ed29e89..954dad52cc 100644 --- a/test/icons/resistor.svg +++ b/test/icons/resistor.svg @@ -1,6 +1,6 @@ - + @icon """ - """ - end @equations begin v ~ i * R end From 645de829a6ced7280b4d8ace0940ce4b46840ab2 Mon Sep 17 00:00:00 2001 From: Venkateshprasad <32921645+ven-k@users.noreply.github.com> Date: Sat, 4 Nov 2023 12:24:54 +0530 Subject: [PATCH 2/2] docs: add `@icon` section to "Components and Connectors" --- docs/src/basics/MTKModel_Connector.md | 54 ++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/docs/src/basics/MTKModel_Connector.md b/docs/src/basics/MTKModel_Connector.md index 0f91025981..db5eb164f8 100644 --- a/docs/src/basics/MTKModel_Connector.md +++ b/docs/src/basics/MTKModel_Connector.md @@ -26,6 +26,7 @@ equations. - `@components`: for listing sub-components of the system - `@equations`: for the list of equations - `@extend`: for extending a base system and unpacking its states + - `@icon` : for embedding the model icon - `@parameters`: for specifying the symbolic parameters - `@structural_parameters`: for specifying non-symbolic parameters - `@variables`: for specifing the states @@ -50,6 +51,7 @@ end end @mtkmodel ModelC begin + @icon "https://github.com/SciML/SciMLDocs/blob/main/docs/src/assets/logo.png" @structural_parameters begin f = sin end @@ -58,6 +60,7 @@ end end @variables begin v(t) = v_var + v_array(t)[1:2, 1:3] end @extend ModelB(; p1) @components begin @@ -69,6 +72,41 @@ end end ``` +#### `@icon` + +An icon can be embedded in 3 ways: + + - URI + - Path to a valid image-file.
+ It can be an absolute path. Or, a path relative to an icon directory; which is + `DEPOT_PATH[1]/mtk_icons` by default and can be changed by setting + `ENV["MTK_ICONS_DIR"]`.
+ Internally, it is saved in the _File URI_ scheme. + +```julia +@mtkmodel WithPathtoIcon begin + @icon "/home/user/.julia/dev/mtk_icons/icon.png" + # Rest of the model definition +end +``` + + - Inlined SVG. + +```julia +@mtkmodel WithInlinedSVGIcon begin + @icon """ + + + """ + # Rest of the model definition +end +``` + +#### `@structural_parameters` begin block + + - This block is for non symbolic input arguements. These are for inputs that usually are not meant to be part of components; but influence how they are defined. One can list inputs like boolean flags, functions etc... here. + - Whenever default values are specified, unlike parameters/variables, they are reflected in the keyword argument list. + #### `@parameters` and `@variables` begin block - Parameters and variables are declared with respective begin blocks. @@ -80,15 +118,10 @@ end ```julia julia> @mtkbuild model_c1 = ModelC(; v = 2.0); -julia> ModelingToolkit.getdefault(model_c.v) +julia> ModelingToolkit.getdefault(model_c1.v) 2.0 ``` -#### `@structural_parameters` begin block - - - This block is for non symbolic input arguements. These are for inputs that usually are not meant to be part of components; but influence how they are defined. One can list inputs like boolean flags, functions etc... here. - - Whenever default values are specified, unlike parameters/variables, they are reflected in the keyword argument list. - #### `@extend` begin block - Partial systems can be extended in a higher system as `@extend PartialSystem(; kwargs)`. @@ -209,11 +242,12 @@ For example, the structure of `ModelC` is: ```julia julia> ModelC.structure -Dict{Symbol, Any} with 6 entries: +Dict{Symbol, Any} with 7 entries: :components => [[:model_a, :ModelA]] - :variables => Dict{Symbol, Dict{Symbol, Any}}(:v=>Dict(:default=>:v_var), :v_array=>Dict(:size=>(4,))) + :variables => Dict{Symbol, Dict{Symbol, Any}}(:v=>Dict(:default=>:v_var), :v_array=>Dict(:size=>(2, 3))) + :icon => URI("https://github.com/SciML/SciMLDocs/blob/main/docs/src/assets/logo.png") :kwargs => Dict{Symbol, Any}(:f=>:sin, :v=>:v_var, :v_array=>nothing, :model_a__k_array=>nothing, :p1=>nothing) :independent_variable => t - :extend => Any[[:p1, :p2], :model_b, :ModelB] - :equations => ["model_a.k1 ~ f(v)"] + :extend => Any[[:p2, :p1], Symbol("#mtkmodel__anonymous__ModelB"), :ModelB] + :equations => ["model_a.k ~ f(v)"] ```