Skip to content

Commit 5be3f43

Browse files
authored
only parse and load config once to construct Demo Page (#68)
1 parent 6d7449b commit 5be3f43

File tree

6 files changed

+60
-45
lines changed

6 files changed

+60
-45
lines changed

src/types/card.jl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,16 @@ function is_democard(file)
4747
end
4848
end
4949

50-
function load_config(card::T, key) where T <: AbstractDemoCard
51-
config = parse(card)
50+
function load_config(card::T, key; config=Dict()) where T <: AbstractDemoCard
51+
isempty(config) && (config = parse(card))
5252

5353
if key == "cover"
5454
haskey(config, key) || return nothing
5555

5656
cover_path = config[key]
57+
if !is_remote_url(cover_path)
58+
cover_path = replace(cover_path, r"[/\\]" => Base.Filesystem.path_separator) # windows compatibility
59+
end
5760
return cover_path
5861
elseif key == "id"
5962
haskey(config, key) || return get_default_id(card)

src/types/julia.jl

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,17 @@ function JuliaDemoCard(path::String)::JuliaDemoCard
8080
# first consturct an incomplete democard, and then load the config
8181
card = JuliaDemoCard(path, "", "", "", "", "", DateTime(0), JULIA_COMPAT, false)
8282

83-
card.cover = load_config(card, "cover")
84-
card.title = load_config(card, "title")
85-
card.date = load_config(card, "date")
86-
card.author = load_config(card, "author")
87-
card.julia = load_config(card, "julia")
83+
config = parse(card)
84+
card.cover = load_config(card, "cover"; config=config)
85+
card.title = load_config(card, "title"; config=config)
86+
card.date = load_config(card, "date"; config=config)
87+
card.author = load_config(card, "author"; config=config)
88+
card.julia = load_config(card, "julia"; config=config)
8889
# default id requires a title
89-
card.id = load_config(card, "id")
90+
card.id = load_config(card, "id"; config=config)
9091
# default description requires a title
91-
card.description = load_config(card, "description")
92-
card.hidden = load_config(card, "hidden")
92+
card.description = load_config(card, "description"; config=config)
93+
card.hidden = load_config(card, "hidden"; config=config)
9394
return card
9495
end
9596

src/types/markdown.jl

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,21 +73,22 @@ function MarkdownDemoCard(path::String)::MarkdownDemoCard
7373
# first consturct an incomplete democard, and then load the config
7474
card = MarkdownDemoCard(path, "", "", "", "", "", DateTime(0), false)
7575

76-
card.cover = load_config(card, "cover")
77-
card.title = load_config(card, "title")
78-
card.date = load_config(card, "date")
79-
card.author = load_config(card, "author")
76+
config = parse(card)
77+
card.cover = load_config(card, "cover"; config=config)
78+
card.title = load_config(card, "title"; config=config)
79+
card.date = load_config(card, "date"; config=config)
80+
card.author = load_config(card, "author"; config=config)
8081

8182
# Unlike JuliaDemoCard, Markdown card doesn't accept `julia` compat field. This is because we
8283
# generally don't know the markdown processing backend. It might be Documenter, but who knows.
8384
# More generally, any badges can just be manually added by demo writter, if they want.
8485
# `date` and `author` fields are added just for convinience.
8586

8687
# default id requires a title
87-
card.id = load_config(card, "id")
88+
card.id = load_config(card, "id"; config=config)
8889
# default description requires a title
89-
card.description = load_config(card, "description")
90-
card.hidden = load_config(card, "hidden")
90+
card.description = load_config(card, "description"; config=config)
91+
card.hidden = load_config(card, "hidden"; config=config)
9192
return card
9293
end
9394

src/types/page.jl

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -113,32 +113,45 @@ function DemoPage(root::String)::DemoPage
113113
msg = "can not find a valid page structure in page dir \"$root\"\nit should have at least one folder as section inside it"
114114
throw(ArgumentError(msg))
115115
end
116-
116+
117+
json_path = joinpath(root, config_filename)
118+
json_config = isfile(json_path) ? JSON.parsefile(json_path) : Dict()
119+
120+
template_file = joinpath(root, get(json_config, "template", template_filename))
121+
config = parse(Val(:Markdown), template_file)
122+
config = merge(json_config, config) # template has higher priority over config file
123+
117124
sections = map(DemoSection, section_paths)
118125
page = DemoPage(root, sections, "", nothing, "")
119-
page.theme = load_config(page, "theme")
126+
page.theme = load_config(page, "theme"; config=config)
120127

121-
section_paths = joinpath.(root, load_config(page, "order"))
122-
ordered_sections = map(DemoSection, section_paths) # TODO: technically, we don't need to regenerate sections here
128+
section_orders = load_config(page, "order"; config=config)
129+
section_orders = map(sections) do sec
130+
findfirst(x-> x == basename(sec.root), section_orders)
131+
end
132+
ordered_sections = sections[section_orders]
123133

124-
title = load_config(page, "title")
134+
title = load_config(page, "title"; config=config)
125135
page.sections = ordered_sections
126136
page.title = title
127137

128138
# default template requires a title
129-
template = load_config(page, "template")
139+
template = load_config(page, "template"; config=config)
130140
page.template = template
131141

132142
return page
133143
end
134144

135-
function load_config(page::DemoPage, key)
136-
json_path = joinpath(page.root, config_filename)
137-
json_config = isfile(json_path) ? JSON.parsefile(json_path) : Dict()
145+
function load_config(page::DemoPage, key; config=Dict())
146+
if isempty(config)
147+
json_path = joinpath(page.root, config_filename)
148+
json_config = isfile(json_path) ? JSON.parsefile(json_path) : Dict()
138149

139-
template_file = joinpath(page.root, get(json_config, "template", template_filename))
140-
config = parse(Val(:Markdown), template_file)
141-
config = merge(json_config, config) # template has higher priority over config file
150+
template_file = joinpath(page.root, get(json_config, "template", template_filename))
151+
config = parse(Val(:Markdown), template_file)
152+
config = merge(json_config, config) # template has higher priority over config file
153+
end
154+
# config could still be an empty dictionary
142155

143156
if key == "order"
144157
haskey(config, key) || return get_default_order(page)

src/types/section.jl

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ See also: [`MarkdownDemoCard`](@ref DemoCards.MarkdownDemoCard), [`DemoPage`](@r
7171
"""
7272
struct DemoSection
7373
root::String
74-
cards::Vector # Why would `Vector{<:AbstractDemoCard}` fail here?
74+
cards::Vector
7575
subsections::Vector{DemoSection}
7676
title::String
7777
description::String
@@ -91,15 +91,16 @@ function DemoSection(root::String)::DemoSection
9191
throw(ArgumentError("section folder $(root) should only hold either cards or subsections"))
9292
end
9393

94-
# first consturct an incomplete section
95-
# then load the config and reconstruct a new one
94+
config_file = joinpath(root, config_filename)
95+
config = isfile(config_file) ? JSON.parsefile(config_file) : Dict()
96+
9697
section = DemoSection(root,
9798
map(democard, card_paths),
9899
map(DemoSection, section_paths),
99100
"",
100101
"")
101102

102-
ordered_paths = joinpath.(root, load_config(section, "order"))
103+
ordered_paths = joinpath.(root, load_config(section, "order"; config=config))
103104
if !isempty(section.cards)
104105
cards = map(democard, ordered_paths)
105106
subsections = []
@@ -108,15 +109,18 @@ function DemoSection(root::String)::DemoSection
108109
subsections = map(DemoSection, ordered_paths)
109110
end
110111

111-
title = load_config(section, "title")
112-
description = load_config(section, "description")
112+
title = load_config(section, "title"; config=config)
113+
description = load_config(section, "description"; config=config)
113114
DemoSection(root, cards, subsections, title, description)
114115
end
115116

116117

117-
function load_config(sec::DemoSection, key)
118-
path = joinpath(sec.root, config_filename)
119-
config = isfile(path) ? JSON.parsefile(path) : Dict()
118+
function load_config(sec::DemoSection, key; config=Dict())
119+
if isempty(config)
120+
config_file = joinpath(sec.root, config_filename)
121+
config = isfile(config_file) ? JSON.parsefile(config_file) : Dict()
122+
end
123+
# config could still be an empty dictionary
120124

121125
if key == "order"
122126
haskey(config, key) || return get_default_order(sec)

src/utils.jl

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -196,13 +196,6 @@ function parse(T::Val, card::AbstractDemoCard)
196196
merge!(config, YAML.load(join(frontmatter, "\n")))
197197
end
198198

199-
if haskey(config, "cover")
200-
if !is_remote_url(config["cover"])
201-
config["cover"] = replace(config["cover"],
202-
r"[/\\]" => Base.Filesystem.path_separator) # windows compatibility
203-
end
204-
end
205-
206199
return config
207200
end
208201
parse(card::JuliaDemoCard) = parse(Val(:Julia), card)

0 commit comments

Comments
 (0)