Skip to content

Commit 6309c02

Browse files
authored
set DemoCards build dir to "docs/src" instead of "docs/src/democards" (#70)
1 parent 1208231 commit 6309c02

File tree

8 files changed

+132
-71
lines changed

8 files changed

+132
-71
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,3 @@
55
Manifest.toml
66
/dev/
77
docs/build/
8-
docs/src/democards

docs/quickstart/index.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,9 @@ The pipeline of [`makedemos`](@ref DemoCards.makedemos) is:
139139
Since all files are generated to `docs/src`, the next step is to leave everything else
140140
to `Documenter.jl` 💯
141141

142-
!!! tip
143-
144-
By default, `makedemos` generates all the necessary files to `docs/src/democards`,
145-
so it's recommended to put your source files into folders outside `docs/src`,
146-
otherwise it will be processed by Documenter _twice_. Also, it's often the case that
147-
you need to add `docs/src/democards` to `.gitignore`.
142+
!!! warning
143+
By default, `makedemos` generates all the necessary files to `docs/src`, this means that the
144+
data you pass to `makedemos` should not be placed at `docs/src`.
148145

149146
For advanced usage of `DemoCards.jl`, you need to understand the core [concepts](@ref concepts) of it.
150147

src/generate.jl

Lines changed: 100 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""
22
makedemos(source::String;
33
root = "<current-directory>",
4-
destination = "democards",
54
src = "src",
65
build = "build",
76
branch = "gh-pages",
@@ -18,10 +17,10 @@ Processing pipeline:
1817
4. save/copy cover images
1918
5. generate postprocess callback function, which includes url-redirection.
2019
21-
!!! note By default, the source demo files are read, processed and save to `docs/src/democards`, so
22-
if you put all source demo files in `docs/src`, there will be a duplication of files and assets.
23-
Thus, it's recommended to not put your original page folder in `docs/src`, and it's prefered to
24-
git ignore `docs/src/democards`
20+
!!! warning
21+
By default, `makedemos` generates all the necessary files to `docs/src/`, this means that the
22+
data you pass to `makedemos` should not be placed at `docs/src/`. A recommendation is to
23+
put folders in `docs/`. For example, `docs/quickstart` is a good choice.
2524
2625
# Inputs
2726
@@ -37,8 +36,8 @@ Processing pipeline:
3736
3837
# Keywords
3938
40-
* `root::String`: should be equal to `Documenter`'s setting. By default it's `"docs"`.
41-
* `destination::String`: The folder name in generated documentation. By default it's `"democards"`.
39+
* `root::String`: should be equal to `Documenter`'s setting. Typically it is `"docs"` if this
40+
function is called in `docs/make.jl` file.
4241
* `src::String`: should be equal to `Documenter`'s setting. By default it's `"src"`.
4342
* `build::String`: should be equal to `Documenter`'s setting. By default it's `"build"`.
4443
* `edit_branch::String`: should be equal to `Documenter`'s setting. By default it's `"master"`.
@@ -85,13 +84,20 @@ For more details of how `config.json` is configured, please check [`DemoCards.De
8584
"""
8685
function makedemos(source::String, templates::Union{Dict, Nothing} = nothing;
8786
root::String = Base.source_dir(),
88-
destination::String = "democards",
8987
src::String = "src",
9088
build::String = "build",
9189
branch::String = "gh-pages",
9290
edit_branch::String = "master",
9391
credit = true)
9492

93+
if !(basename(pwd()) == "docs" || basename(root) == "docs" || root == preview_build_dir())
94+
# special cases that warnings are not printed:
95+
# 1. called from `docs/make.jl`
96+
# 2. called from `preview_demos`
97+
# 3. pwd() in `docs` -- REPL
98+
@warn "Suspicious `root` setting: typically `makedemos` should be called from `docs/make.jl`. " pwd=pwd() root
99+
end
100+
95101
root = abspath(root)
96102
page_root = abspath(root, source)
97103

@@ -102,6 +108,16 @@ function makedemos(source::String, templates::Union{Dict, Nothing} = nothing;
102108

103109
page = DemoPage(page_root)
104110

111+
relative_root = basename(page)
112+
113+
# Where files are generated by DemoCards for Documenter.makedocs
114+
# e.g "$PROJECT_ROOT/docs/src/quickstart"
115+
absolute_root = abspath(root, src, relative_root)
116+
117+
if page_root == absolute_root
118+
throw(ArgumentError("Demo page $page_root should not be placed at \"docs/$src\" folder."))
119+
end
120+
105121
config_file = joinpath(page.root, config_filename)
106122
if !isnothing(templates)
107123
Base.depwarn(
@@ -121,13 +137,6 @@ function makedemos(source::String, templates::Union{Dict, Nothing} = nothing;
121137
theme_assets = nothing
122138
end
123139

124-
relative_root = joinpath(destination, basename(page))
125-
126-
# Where files are generated by DemoCards for Documenter.makedocs
127-
# e.g "$PROJECT_ROOT/docs/src/democards/quickstart"
128-
absolute_root = joinpath(root, src, relative_root)
129-
isdir(absolute_root) && rm(absolute_root; force=true, recursive=true)
130-
131140
# we can directly pass it to Documenter.makedocs
132141
if isnothing(templates)
133142
out_path = walkpage(page; flatten=false) do item
@@ -137,37 +146,75 @@ function makedemos(source::String, templates::Union{Dict, Nothing} = nothing;
137146
out_path = joinpath(relative_root, "index.md")
138147
end
139148

140-
@info "SetupDemoCardsDirectory: setting up $(source) directory."
141-
rm(absolute_root; force=true, recursive=true)
142-
mkpath(absolute_root)
143-
# hard coded "covers" should be consistant to card template
144-
isnothing(templates) || mkpath(joinpath(absolute_root, "covers"))
145-
146-
# make a copy before pipeline because `save_democards` modifies card path
147-
source_files = [x.path for x in walkpage(page)[2]]
148-
149-
# pipeline
150-
# for themeless version, we don't need to generate covers and index page
151-
copy_assets(absolute_root, page)
152-
# WARNING: julia cards are reconfigured here
153-
save_democards(absolute_root, page;
154-
project_root = root,
155-
src = src,
156-
credit = credit,
157-
nbviewer_root_url = get_nbviewer_root_url(branch))
158-
isnothing(templates) || save_cover(joinpath(absolute_root, "covers"), page)
159-
isnothing(templates) || generate(joinpath(absolute_root, "index.md"), page, templates)
160-
161-
# pipeline: generate postprocess callback function
162-
postprocess_cb = ()->begin
163-
@info "Redirect URL: redirect docs-edit-link for demos in $(source) directory."
164-
isnothing(templates) || push!(source_files, joinpath(page_root, "index.md"))
165-
foreach(source_files) do source_file
166-
redirect_link(source_file, source, root, destination, src, build, edit_branch)
149+
@info "SetupDemoCardsDirectory: setting up \"$(source)\" directory."
150+
if isdir(absolute_root)
151+
# a typical and probably safe case -- that we're still in docs/ folder
152+
trigger_prompt = !endswith(dirname(absolute_root), joinpath("docs", "src"))
153+
154+
if trigger_prompt
155+
@warn "DemoCards build dir $absolute_root already exists.\nThis should only happen when you are using DemoCards incorrectly."
156+
# Should never reach this in CI environment
157+
clean_builddir = input_bool("It might contain important data, do you still want to remove it?")
158+
else
159+
clean_builddir = true
160+
end
161+
if clean_builddir
162+
@info "Remove DemoCards build dir: $absolute_root"
163+
rm(absolute_root; force=true, recursive=true)
164+
else
165+
error("Stopped demos build.")
167166
end
168167
end
169168

170-
return out_path, postprocess_cb, theme_assets
169+
mkpath(absolute_root)
170+
try
171+
# hard coded "covers" should be consistant to card template
172+
isnothing(templates) || mkpath(joinpath(absolute_root, "covers"))
173+
174+
# make a copy before pipeline because `save_democards` modifies card path
175+
source_files = [x.path for x in walkpage(page)[2]]
176+
177+
# pipeline
178+
# for themeless version, we don't need to generate covers and index page
179+
copy_assets(absolute_root, page)
180+
# WARNING: julia cards are reconfigured here
181+
save_democards(absolute_root, page;
182+
project_root = root,
183+
src = src,
184+
credit = credit,
185+
nbviewer_root_url = get_nbviewer_root_url(branch))
186+
isnothing(templates) || save_cover(joinpath(absolute_root, "covers"), page)
187+
isnothing(templates) || generate(joinpath(absolute_root, "index.md"), page, templates)
188+
189+
# pipeline: generate postprocess callback function
190+
postprocess_cb = ()->begin
191+
@info "Redirect page URL: redirect docs-edit-link for demos in \"$(source)\" directory."
192+
isnothing(templates) || push!(source_files, joinpath(page_root, "index.md"))
193+
foreach(source_files) do source_file
194+
redirect_link(source_file, source, root, src, build, edit_branch)
195+
end
196+
197+
@info "Clean up DemoCards build dir: \"$source\""
198+
rm(absolute_root; force=true, recursive=true)
199+
200+
if !isnothing(theme_assets)
201+
assets_path = abspath(root, src, theme_assets)
202+
rm(assets_path, force=true)
203+
if(isempty(readdir(dirname(assets_path))))
204+
rm(dirname(assets_path))
205+
end
206+
end
207+
end
208+
209+
return out_path, postprocess_cb, theme_assets
210+
211+
catch err
212+
# clean up build dir if anything wrong happens here so that we _hopefully_ never trigger the
213+
# user prompt logic before the build process.
214+
rm(absolute_root; force=true, recursive=true)
215+
@error "Errors when building demo dir" pwd=pwd() source root src
216+
rethrow(err)
217+
end
171218
end
172219

173220
function generate(file::String, page::DemoPage, args...)
@@ -347,13 +394,13 @@ end
347394
### postprocess
348395

349396
"""
350-
redirect_link(src_file, source, root, destination, src, build, edit_branch)
397+
redirect_link(src_file, source, root, src, build, edit_branch)
351398
352399
Redirect the "Edit On GitHub" link of generated demo files to its original url, without
353400
this a 404 error is expected.
354401
"""
355-
function redirect_link(source_file, source, root, destination, src, build, edit_branch)
356-
build_file = get_build_file(source_file, source, destination, build)
402+
function redirect_link(source_file, source, root, src, build, edit_branch)
403+
build_file = get_build_file(source_file, source, build)
357404
if !isfile(build_file)
358405
@warn "$build_file doesn't exists, skip"
359406
return nothing
@@ -370,16 +417,16 @@ function redirect_link(source_file, source, root, destination, src, build, edit_
370417
isnothing(m) && return nothing
371418
build_url = m.captures[1]
372419

373-
src_url = get_source_url(build_url, source, basename(source_file), src, destination)
420+
src_url = get_source_url(build_url, source, basename(source_file), src)
374421
new_contents = replace(contents, build_url=>src_url)
375422
end
376423
write(build_file, new_contents)
377424
end
378425

379-
function get_source_url(build_url, source, cardname, src, destination)
426+
function get_source_url(build_url, source, cardname, src)
380427
# given input:
381428
# - projct_root: "$REPO/blob/$edit_branch"
382-
# - build_root: "$projct_root/$docs_root/$src/$destination"
429+
# - build_root: "$projct_root/$docs_root/$src"
383430
# - build_dir: "$build_root/$prefix/$page/$section/$subsection"
384431
# - build_url: "$build_dir/$cardfile"
385432
# example of build_url:
@@ -393,28 +440,27 @@ function get_source_url(build_url, source, cardname, src, destination)
393440
source = replace(source, Base.Filesystem.path_separator => "/")
394441

395442
repo, path = strip.(split(build_url, "/blob/"; limit=2), '/')
396-
root_to_subsection = replace(splitdir(path)[1], "$(src)/$(destination)/" => ""; count=1)
443+
root_to_subsection = replace(splitdir(path)[1], "$(src)/" => ""; count=1)
397444
root_to_subsection = replace(root_to_subsection, "/$(basename(source))/" => "/$(source)/"; count=1)
398445
src_url = join([repo, "blob", root_to_subsection, cardname], "/")
399446

400447
return src_url
401448
end
402449

403-
function get_build_file(source_file, source, destination, build)
450+
function get_build_file(source_file, source, build)
404451
# given inputs:
405452
# - source_file: "$source_root/$prefix/$page/$section/$subsection/$card.md"
406453
# - source: "$prefix/$page
407-
# - destination: "democards"
408454
# - build: "build"
409455
# we need to generate:
410-
# - build_root: "$source_root/$build/$destination"
456+
# - build_root: "$source_root/$build"
411457
# - build_dir: "$build_root/$page/$section/$subsection
412458
# - build_file: "$build_dir/$card.html" or "$build_dir/$card/index.html"
413459

414460
sep = Base.Filesystem.path_separator
415461
# add trailing / to avoid incorrect substring match
416462
source_root = first(split(source_file, source * sep; limit=2))
417-
build_root = joinpath(source_root, build, destination)
463+
build_root = joinpath(source_root, build)
418464
prefix, page = splitdir(source)
419465

420466
source_dir, name = splitdir(source_file)

src/preview.jl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ function preview_demos(demo_path::String;
3838
# hard code these args in a sandbox environment -- there's no need for customization
3939
build = "build"
4040
src = "src"
41-
destination = "democards"
4241

4342
demo_path = abspath(rstrip(demo_path, ['/', '\\']))
4443
ispath(demo_path) || throw(ArgumentError("demo path does not exists: $demo_path"))
@@ -84,14 +83,13 @@ function preview_demos(demo_path::String;
8483
root = build_dir,
8584
src = src,
8685
build = build,
87-
destination = destination,
8886
edit_branch = edit_branch,
8987
credit = credit
9088
)
9189

9290
# In cases that addtional Documenter pipeline is not needed
9391
# This is mostly for test usage right now and might be changed if there is better solution
94-
require_html || return abspath(build_dir, src, destination, basename(page_dir))
92+
require_html || return abspath(build_dir, src, basename(page_dir))
9593

9694
format = Documenter.HTML(
9795
edit_link = edit_branch,

src/utils.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,3 +341,24 @@ end
341341

342342

343343
is_remote_url(path) = !isnothing(match(r"^https?://", path))
344+
345+
346+
"""
347+
input_bool(prompt)::Bool
348+
349+
Print `prompt` message and trigger user input for confirmation.
350+
"""
351+
function input_bool(prompt)
352+
while true
353+
println(prompt, " [y/n]")
354+
response = readline()
355+
length(response) == 0 && continue
356+
reply = lowercase(first(strip(response)))
357+
if reply == 'y'
358+
return true
359+
elseif reply =='n'
360+
return false
361+
end
362+
# Otherwise loop and repeat the prompt
363+
end
364+
end

test/generate.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
cp(abs_root, tmp_root, force=true)
1919
templates, theme = cardtheme(root=root)
2020
path, post_process_cb = @suppress_err makedemos(tmp_root, templates, root=root)
21-
@test @suppress_err path == joinpath("democards", "default", "index.md")
21+
@test @suppress_err path == joinpath("default", "index.md")
2222
@test theme == joinpath("democards", "gridtheme.css")
2323
end
2424

test/preview.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
demo_file = joinpath(joinpath(page_dir, "subsection_2"), demo_file)
1515
@test_reference joinpath("references", "preview", basename(demo_file)) read(demo_file, String) by=ignore_CR
1616
end
17-
@test "gridtheme.css" in readdir(dirname(page_dir))
17+
@test "gridtheme.css" in readdir(joinpath(dirname(page_dir), "democards"))
1818
end
1919

2020
@testset "section with non page structure" begin

test/utils.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,14 @@ end
8080

8181
@testset "url_redirect" begin
8282
source = "quickstart"
83-
build_url = "https://github.com/johnnychen94/DemoCards.jl/blob/master/docs/src/democards/quickstart/usage_example/julia_demos/2.cover_on_the_fly.md"
83+
build_url = "https://github.com/johnnychen94/DemoCards.jl/blob/master/docs/src/quickstart/usage_example/julia_demos/2.cover_on_the_fly.md"
8484
src_url = "https://github.com/johnnychen94/DemoCards.jl/blob/master/docs/quickstart/usage_example/julia_demos/2.cover_on_the_fly.jl"
85-
@test src_url == DemoCards.get_source_url(build_url, source, "2.cover_on_the_fly.jl", "src", "democards")
85+
@test src_url == DemoCards.get_source_url(build_url, source, "2.cover_on_the_fly.jl", "src")
8686

87-
source = Sys.iswindows() ? raw"theme_gallery\grid" : "theme_gallery/grid"
88-
build_url = "https://github.com/johnnychen94/DemoCards.jl/blob/master/docs/src/democards/grid/grid_section_1/grid_subsection_1/grid_card_1.md"
87+
source = joinpath("theme_gallery", "grid")
88+
build_url = "https://github.com/johnnychen94/DemoCards.jl/blob/master/docs/src/grid/grid_section_1/grid_subsection_1/grid_card_1.md"
8989
src_url = "https://github.com/johnnychen94/DemoCards.jl/blob/master/docs/theme_gallery/grid/grid_section_1/grid_subsection_1/grid_card_1.md"
90-
@test src_url == DemoCards.get_source_url(build_url, source, "grid_card_1.md", "src", "democards")
90+
@test src_url == DemoCards.get_source_url(build_url, source, "grid_card_1.md", "src")
9191
end
9292

9393
@testset "walkpage" begin

0 commit comments

Comments
 (0)