From 4f4a78d0488ad5724b347d8a9d4161ca04dc84da Mon Sep 17 00:00:00 2001 From: Toby Hodges Date: Tue, 15 Aug 2023 10:52:27 +0100 Subject: [PATCH 1/7] add spoiler class of accordion --- inst/rmarkdown/lua/lesson.lua | 27 +++++++++++++++++++++------ tests/testthat/_snaps/render_html.md | 1 - 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/inst/rmarkdown/lua/lesson.lua b/inst/rmarkdown/lua/lesson.lua index 68b47c3f..76cd1a27 100644 --- a/inst/rmarkdown/lua/lesson.lua +++ b/inst/rmarkdown/lua/lesson.lua @@ -17,6 +17,7 @@ local blocks = { ["checklist"] = "check-square", ["solution"] = "none", ["hint"] = "none", + ["spoiler"] = "none", ["discussion"] = "message-circle", ["testimonial"] = "heart", ["keypoints"] = "key", @@ -31,6 +32,7 @@ local block_counts = { ["checklist"] = 0, ["solution"] = 0, ["hint"] = 0, + ["spoiler"] = 0, ["discussion"] = 0, ["testimonial"] = 0, ["keypoints"] = 0, @@ -185,12 +187,17 @@ local button_headings = {

{{title}}

]], + ["spoiler"] = [[ +

+ {{title}} +

]], } local accordion_titles = { ["instructor"] = "Instructor Note", ["hint"] = "Give me a hint", - ["solution"] = "Show me the solution" + ["solution"] = "Show me the solution", + ["spoiler"] = "Show details" } local accordion_button = [[ @@ -250,7 +257,9 @@ accordion = function(el, class) -- the whole package local main_div = pandoc.Div({accordion_item}) local main_class = {"accordion", "instructor-note", "accordion-flush"} - if class ~= "instructor" then + if class == "spoiler" then + main_class[2] = "spoiler-accordion" + elseif class ~= "instructor" then main_class[2] = "challenge-accordion" end main_div.identifier = div_id @@ -357,16 +366,22 @@ handle_our_divs = function(el) -- Accordion blocks: -- - -- Instructor Notes, Solutions, and Hints are all blocks that are contained in - -- accordion blocks. For historical reasons, solutions are normally embedded - -- in challenge blocks, but because of the way pandoc traverses the AST, we - -- need to process these FIRST and then handle their positioning in the + -- Instructor Notes, Solutions, Hints, and Spoilers are all blocks + -- that are contained in accordion blocks. + -- For historical reasons, solutions are normally embedded + -- in challenge blocks, but because of the way pandoc traverses the AST, + -- we need to process these FIRST and then handle their positioning in the -- challenge block phase. v,i = el.classes:find("instructor") if i ~= nil then return(accordion(el, "instructor")) end + v,i = el.classes:find("spoiler") + if i ~= nil then + return(accordion(el, "spoiler")) + end + v,i = el.classes:find("solution") if i ~= nil then return(accordion(el, "solution")) diff --git a/tests/testthat/_snaps/render_html.md b/tests/testthat/_snaps/render_html.md index b402e4a2..7eb28cdf 100644 --- a/tests/testthat/_snaps/render_html.md +++ b/tests/testthat/_snaps/render_html.md @@ -394,4 +394,3 @@

This should be

- From 9d42722ca7b3b5764aad641a400e6295196fb052 Mon Sep 17 00:00:00 2001 From: Toby Hodges Date: Thu, 17 Aug 2023 12:51:35 +0100 Subject: [PATCH 2/7] add icon for spoiler divs --- inst/rmarkdown/lua/lesson.lua | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/inst/rmarkdown/lua/lesson.lua b/inst/rmarkdown/lua/lesson.lua index 76cd1a27..3a23d0bb 100644 --- a/inst/rmarkdown/lua/lesson.lua +++ b/inst/rmarkdown/lua/lesson.lua @@ -17,7 +17,7 @@ local blocks = { ["checklist"] = "check-square", ["solution"] = "none", ["hint"] = "none", - ["spoiler"] = "none", + ["spoiler"] = "eye", ["discussion"] = "message-circle", ["testimonial"] = "heart", ["keypoints"] = "key", @@ -225,10 +225,18 @@ accordion = function(el, class) if title == CLASS or title == nil or title == "" then title = accordion_titles[class] end + -- insert icon before heading if this is a spoiler accordion -- + if class ~= "spoiler" then + heading = button_headings[class] + else + local this_icon = blocks["spoiler"] + heading = button_headings[class] + heading = ""..heading + end -- constructing the button that contains a heading local this_button = accordion_button - this_button = this_button:gsub("{{heading}}", button_headings[class]) + this_button = this_button:gsub("{{heading}}", heading) this_button = this_button:gsub("{{title}}", title) this_button = this_button:gsub("{{class}}", class) this_button = this_button:gsub("{{id}}", label) From 6ce0822453b839744018c02ae30ae40d6a9aea26 Mon Sep 17 00:00:00 2001 From: Toby Hodges Date: Thu, 17 Aug 2023 12:51:54 +0100 Subject: [PATCH 3/7] typo fixes --- inst/rmarkdown/lua/lesson.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inst/rmarkdown/lua/lesson.lua b/inst/rmarkdown/lua/lesson.lua index 3a23d0bb..7f227548 100644 --- a/inst/rmarkdown/lua/lesson.lua +++ b/inst/rmarkdown/lua/lesson.lua @@ -305,12 +305,12 @@ end challenge_block = function(el) -- The challenge blocks no longer contain solutions nested inside. Instead, - -- the soltuions (and hints) are piled at the end of the block, so series of + -- the solutions (and hints) are piled at the end of the block, so series of -- challenge/solutions need to be separated. -- The challenge train is a list to contain all the divs local challenge_train = pandoc.List:new() - -- If the challenge contains multipl solutions or hints, we need to indicate + -- If the challenge contains multiple solutions or hints, we need to indicate -- that the following challenges/solutions are continuations. local this_head = get_header(el, 3) local next_head = this_head:clone() From b79930a93a5d208563e478df51f3541e42e00371 Mon Sep 17 00:00:00 2001 From: Toby Hodges Date: Tue, 22 Aug 2023 10:13:27 +0100 Subject: [PATCH 4/7] Use note-square class for icon box Co-authored-by: Zhian N. Kamvar --- inst/rmarkdown/lua/lesson.lua | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/inst/rmarkdown/lua/lesson.lua b/inst/rmarkdown/lua/lesson.lua index 7f227548..5de76169 100644 --- a/inst/rmarkdown/lua/lesson.lua +++ b/inst/rmarkdown/lua/lesson.lua @@ -188,9 +188,10 @@ local button_headings = { {{title}} ]], ["spoiler"] = [[ -

+

+
{{title}} -

]], + ]], } local accordion_titles = { @@ -225,18 +226,10 @@ accordion = function(el, class) if title == CLASS or title == nil or title == "" then title = accordion_titles[class] end - -- insert icon before heading if this is a spoiler accordion -- - if class ~= "spoiler" then - heading = button_headings[class] - else - local this_icon = blocks["spoiler"] - heading = button_headings[class] - heading = ""..heading - end -- constructing the button that contains a heading local this_button = accordion_button - this_button = this_button:gsub("{{heading}}", heading) + this_button = this_button:gsub("{{heading}}", button_headings[class]) this_button = this_button:gsub("{{title}}", title) this_button = this_button:gsub("{{class}}", class) this_button = this_button:gsub("{{id}}", label) From 8aa820533cc0b805d652359071343f250aeafdc6 Mon Sep 17 00:00:00 2001 From: Toby Hodges Date: Tue, 22 Aug 2023 10:23:25 +0100 Subject: [PATCH 5/7] add spoiler block to example for testing --- tests/testthat/examples/ex.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/testthat/examples/ex.md b/tests/testthat/examples/ex.md index bc67f8e5..55f0672d 100644 --- a/tests/testthat/examples/ex.md +++ b/tests/testthat/examples/ex.md @@ -45,6 +45,12 @@ This should be aside ::: +::: spoiler + +That fin on the rear end of a car + +::: + ::: nothing This should be From 0e267ffc0b58690ad0390b77503e0b6095ade996 Mon Sep 17 00:00:00 2001 From: "Zhian N. Kamvar" Date: Tue, 29 Aug 2023 11:41:39 -0700 Subject: [PATCH 6/7] allow spoiler tests to worjk --- tests/testthat/_snaps/render_html.md | 78 ++++++++++++++++++++++++---- tests/testthat/test-render_html.R | 16 +++--- 2 files changed, 78 insertions(+), 16 deletions(-) diff --git a/tests/testthat/_snaps/render_html.md b/tests/testthat/_snaps/render_html.md index 7eb28cdf..2c70b003 100644 --- a/tests/testthat/_snaps/render_html.md +++ b/tests/testthat/_snaps/render_html.md @@ -170,8 +170,8 @@ , Div ( "collapseSolution1" , [ "accordion-collapse" , "collapse" ] - , [ ( "[solution collapse]" ) - , ( "[solution collapse]" ) + , [ ( "[Solution hidden]" ) + , ( "[Solution hidden]" ) ] ) [ Div @@ -202,8 +202,8 @@ , Div ( "collapseInstructor1" , [ "accordion-collapse" , "collapse" ] - , [ ( "[instructor collapse]" ) - , ( "[instructor collapse]" ) + , [ ( "[Instructor hidden]" ) + , ( "[Instructor hidden]" ) ] ) [ Div @@ -221,6 +221,48 @@ ] ] ] + , Div + ( "accordionSpoiler1" + , [ "accordion" , "spoiler-accordion" , "accordion-flush" ] + , [] + ) + [ Div + ( "" , [ "accordion-item" ] , [] ) + [ RawBlock + (Format "html") + "" + , Div + ( "collapseSpoiler1" + , [ "accordion-collapse" , "collapse" ] + , [ ( "[Spoiler hidden]" ) + , ( "[Spoiler hidden]" ) + ] + ) + [ Div + ( "" , [ "accordion-body" ] , [] ) + [ Para + [ Str "That" + , Space + , Str "fin" + , Space + , Str "on" + , Space + , Str "the" + , Space + , Str "rear" + , Space + , Str "end" + , Space + , Str "of" + , Space + , Str "a" + , Space + , Str "car" + ] + ] + ] + ] + ] , Div ( "" , [ "nothing" ] , [] ) [ Para @@ -364,8 +406,8 @@ Write now - [solution collapse] - [solution collapse] +

just write it, silly.

@@ -381,16 +423,34 @@ Instructor Note - [instructor collapse] - [instructor collapse] - [instructor collapse] +

This should be aside

+
+
+ +
+
+

That fin on the rear end of a car

+
+
+
+

This should be

+ diff --git a/tests/testthat/test-render_html.R b/tests/testthat/test-render_html.R index 57d7e67d..a5878e85 100644 --- a/tests/testthat/test-render_html.R +++ b/tests/testthat/test-render_html.R @@ -89,8 +89,8 @@ test_that("pandoc structure is rendered correctly", { } skip_on_os("windows") formation = function(x) { - x <- sub("(data-bs-parent|aria-labelledby).+?Instructor1", "[instructor collapse]", x) - sub("(data-bs-parent|aria-labelledby).+?Solution1", "[solution collapse]", x) + rgx <- "(data-bs-parent|aria-labelledby).+?(Instructor|Solution|Spoiler)1" + return(sub(rgx, "[\\2 hidden]", x)) } expect_snapshot(cat(readLines(out), sep = "\n"), transform = formation) }) @@ -147,11 +147,13 @@ test_that("render_html applies the internal lua filter", { } skip_on_os("windows") formation = function(x) { - x <- sub("[<]div id[=]\"collapseSolution1\".+", "[solution collapse]", x) - x <- sub("[<]div id[=]\"collapseInstructor1\".+", "[instructor collapse]", x) - x <- sub("(data-bs-parent|aria-labelledby).+?Instructor1.+$", "[instructor collapse]", x) - sub("(data-bs-parent|aria-labelledby).+?Solution1.+$", "[solution collapse]", x) - + open <- "[<]div id[=]\"collapse(Instructor|Solution|Spoiler)\\d\".+" + mid <- "(data-bs-parent|aria-labelledby).+?(Instructor|Solution|Spoiler)\\d[\"]$" + close <- "(data-bs-parent|aria-labelledby).+?(Instructor|Solution|Spoiler)\\d.+[>]$" + x <- sub(open, "
", x) + return(x) } expect_snapshot(cat(res), transform = formation) }) From 8d8e181784b02c85389e76a388a3779d973a4dc8 Mon Sep 17 00:00:00 2001 From: "Zhian N. Kamvar" Date: Wed, 30 Aug 2023 11:24:50 -0700 Subject: [PATCH 7/7] bump version; add NEWS --- DESCRIPTION | 2 +- NEWS.md | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index c716fece..c161f71a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: sandpaper Title: Create and Curate Carpentries Lessons -Version: 0.12.5 +Version: 0.13.0 Authors@R: c( person(given = "Zhian N.", family = "Kamvar", diff --git a/NEWS.md b/NEWS.md index 9a095814..f8409d05 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,11 @@ -# sandpaper 0.12.5 (unreleased) +# sandpaper 0.13.0 (unreleased) + +## NEW FEATURES + +* The new `spoiler` class of fenced div will allow authors to specify an + expandable section of content that is collapsed by default. This replaces the + former paradigm of using "floating solution" blocks to present options for + installation on different platforms. (implemented: @tobyhodges, #502) ## BUG FIX