94 lines
2.6 KiB
Julia
94 lines
2.6 KiB
Julia
using DataStructures
|
|
|
|
function dictify2(x; keytype::Type=Any, sort_order::Union{Nothing, Vector}=nothing)
|
|
# Dict-like objects
|
|
if x isa AbstractDict
|
|
out = OrderedDict{keytype, Any}()
|
|
|
|
# 1. Process and normalize all keys from the input dictionary
|
|
processed_dict = OrderedDict{keytype, Any}()
|
|
for (k, v) in x
|
|
if keytype === String
|
|
newk = string(k)
|
|
elseif keytype === Symbol
|
|
newk = Symbol(string(k))
|
|
else
|
|
newk = k
|
|
end
|
|
processed_dict[newk] = dictify(v; keytype=keytype, sort_order=sort_order)
|
|
end
|
|
|
|
# 2. If a sort order is specified, apply it
|
|
if !isnothing(sort_order)
|
|
# Normalize the sort_order elements to match the requested keytype
|
|
normalized_order = map(sort_order) do tk
|
|
if keytype === String
|
|
return string(tk)
|
|
elseif keytype === Symbol
|
|
return Symbol(string(tk))
|
|
else
|
|
return tk
|
|
end
|
|
end
|
|
|
|
# First, insert keys that match the requested order
|
|
for target_key in normalized_order
|
|
if haskey(processed_dict, target_key)
|
|
out[target_key] = processed_dict[target_key]
|
|
end
|
|
end
|
|
|
|
# Then, append any remaining keys that weren't in the sort_order
|
|
for (k, v) in processed_dict
|
|
if !haskey(out, k)
|
|
out[k] = v
|
|
end
|
|
end
|
|
else
|
|
# If no sort order is given, just use the processed dict
|
|
out = processed_dict
|
|
end
|
|
|
|
return out
|
|
|
|
# Arrays / vectors: map elements recursively
|
|
elseif x isa AbstractArray
|
|
return [dictify(element; keytype=keytype, sort_order=sort_order) for element in x]
|
|
|
|
# Everything else: return as-is
|
|
else
|
|
return x
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
function dict_to_string_html2(d::AbstractDict; indent_level=1, indent_str=" ")
|
|
lines = String[]
|
|
padding = indent_str ^ indent_level
|
|
|
|
# Sort keys for predictable, clean output
|
|
for k in keys(d)
|
|
v = d[k]
|
|
|
|
if v isa AbstractDict
|
|
# Open tag, recurse for children, then close tag
|
|
push!(lines, "$padding<$k>")
|
|
ind_level = indent_level + 1
|
|
push!(lines, dict_to_string_html(v; indent_level=ind_level, indent_str=indent_str))
|
|
push!(lines, "$padding</$k>")
|
|
else
|
|
# Leaf node: put key and value on a single line
|
|
push!(lines, "$padding<$k>$v</$k>")
|
|
end
|
|
end
|
|
return join(lines, "\n")
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|