Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix block anchors #467

Merged
merged 8 commits into from
May 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# sandpaper 0.11.18 (unreleased)

## BUG FIX

* Callout block anchor links now point to the correct ID of the block derived
from the title of the block (as opposed to the generic ID).
(reported: @debpaul,
https://github.com/datacarpentry/OpenRefine-ecology-lesson/issues/292 and
@bencomp, #454; fixed: @zkamvar, #467)


## MISC

* The internal function `sandpaper:::render_html()` now explicitly sets the
Expand Down
16 changes: 15 additions & 1 deletion R/utils-xml.R
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,22 @@ fix_callouts <- function(nodes = NULL) {
h3 <- xml2::xml_find_all(callouts, "./div/h3")
xml2::xml_set_attr(h3, "class", "callout-title")
inner_div <- xml2::xml_parent(h3)
# remove the "section level3 callout-title" attrs
xml2::xml_set_attr(inner_div, "class", "callout-inner")
add_anchors(h3, xml2::xml_attr(callouts, "id"))
# Get the heading IDS (because we use section headings, the IDs are anchored
# to the section div and not the heading element)
# <div class="section level3 callout-title callout-inner">
# <h3>Heading for this callout</h3>
# </div>
ids <- xml2::xml_attr(inner_div, "id")
# get the callout ID in the cases where they are missing
replacements <- xml2::xml_attr(callouts, "id")
ids <- ifelse(is.na(ids), replacements, ids)
# add the anchors and then set the attributes in the correct places.
add_anchors(h3, ids)
xml2::xml_set_attr(h3, "id", NULL)
# we replace the callout ID with the correct ID
xml2::xml_set_attr(callouts, "id", ids)
invisible(nodes)
}

Expand Down
5 changes: 3 additions & 2 deletions inst/rmarkdown/lua/lesson.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ function Set (list)
return set
end


local blocks = {
["callout"] = "bell",
["objectives"] = "none",
Expand Down Expand Up @@ -265,10 +264,12 @@ callout_block = function(el)
if this_icon == nil then
return el
end
-- Get the header and create the ID
local header = get_header(el, 3)

block_counts[classes[1]] = block_counts[classes[1]] + 1
callout_id = classes[1]..block_counts[classes[1]]
classes:insert(1, "callout")
local header = get_header(el, 3)

local icon = pandoc.RawBlock("html",
"<i class='callout-icon' data-feather='"..this_icon.."'></i>")
Expand Down
31 changes: 31 additions & 0 deletions tests/testthat/examples/callout-ids.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<body>
<div id="markdown" class="section level2">
<h2>Markdown</h2>
<p>Here is an example of a callout block</p>
<div id="discussion1" class="callout discussion">
<div class="callout-square">
<i class="callout-icon" data-feather="message-circle"></i>
</div>
<div class="section level3 callout-title callout-inner">
<h3 class="callout-title">Challenge</h3>
<div class="callout-content">
<p>How do you write markdown divs?</p>
</div>
</div>
</div>
</div>
<div id="prereq1" class="callout prereq">
<div class="callout-square">
<i class="callout-icon" data-feather="check"></i>
</div>
<div id="wait-what" class="section level3 callout-title callout-inner">
<h3 class="callout-title">Wait what?</h3>
<div class="callout-content">
<p>preeeee</p>
</div>
</div>
</div>
</body>
</html>
21 changes: 21 additions & 0 deletions tests/testthat/test-utils-xml.R
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,27 @@ test_that("paths in instructor view that are nested or not HTML get diverted", {
})


test_that("callout ids are processed correctly", {
html_test <- xml2::read_html(test_path("examples/callout-ids.html"))
fix_callouts(html_test)
anchors <- xml2::xml_find_all(html_test, ".//a")
headings <- xml2::xml_find_all(html_test, ".//h3")
callouts <- xml2::xml_find_all(html_test,
".//div[starts-with(@class, 'callout ')]")
expect_length(anchors, 2)
expect_length(callouts, 2)
expect_length(headings, 2)
# headings should not have IDS
expect_equal(xml2::xml_has_attr(headings, "id"), c(FALSE, FALSE))
# callouts should have these IDS
expect_equal(xml2::xml_has_attr(callouts, "id"), c(TRUE, TRUE))
# The IDs should be what we expect
ids <- xml2::xml_attr(callouts, "id")
expect_equal(ids, c("discussion1", "wait-what"))
# The IDs should match the anchors
expect_equal(paste0("#", ids), xml2::xml_attr(anchors, "href"))
})


test_that("empty args result in nothing happening", {
expect_null(fix_nodes())
Expand Down