Skip to content

Commit

Permalink
Merge pull request #484 from harvard-edge/widget_quiz
Browse files Browse the repository at this point in the history
updating quiz widget
  • Loading branch information
profvjreddi authored Nov 18, 2024
2 parents 521c1f8 + bf0a4cd commit 2a44e45
Show file tree
Hide file tree
Showing 29 changed files with 3,016 additions and 4 deletions.
7 changes: 7 additions & 0 deletions _extensions/quarto-ext/lightbox/_extension.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
title: Lightbox
author: Posit Software, PBC
version: 0.1.9
quarto-required: ">=1.2.198"
contributes:
filters:
- lightbox.lua
9 changes: 9 additions & 0 deletions _extensions/quarto-ext/lightbox/lightbox.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@



body:not(.glightbox-mobile) div.gslide div.gslide-description,
body:not(.glightbox-mobile) div.gslide-description .gslide-title,
body:not(.glightbox-mobile) div.gslide-description .gslide-desc {
color: var(--quarto-body-color);
background-color: var(--quarto-body-bg);
}
251 changes: 251 additions & 0 deletions _extensions/quarto-ext/lightbox/lightbox.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
-- whether we're automatically lightboxing
local auto = false

-- whether we need lightbox dependencies added
local needsLightbox = false

-- a counter used to ensure each image is in its own gallery
local imgCount = 0

-- attributes to forward from the image to the newly created link
local kDescription = "description"
local kForwardedAttr = {
"title", kDescription, "desc-position",
"type", "effect", "zoomable", "draggable"
}

local kLightboxClass = "lightbox"
local kNoLightboxClass = "nolightbox"
local kGalleryPrefix = "quarto-lightbox-gallery-"

-- A list of images already within links that we can use to filter
local imagesWithinLinks = pandoc.List({})

local function readAttrValue(el, attrName)
if attrName == kDescription then
local doc = pandoc.read(el.attr.attributes[attrName])
local attrInlines = doc.blocks[1].content
return pandoc.write(pandoc.Pandoc(attrInlines), "html")
else
return el[attrName]
end

end

return {
{
Meta = function(meta)

-- If the mode is auto, we need go ahead and
-- run if there are any images (ideally we would)
-- filter to images in the body, but that can be
-- left for future me to deal with
-- supports:
-- lightbox: auto
-- or
-- lightbox:
-- match: auto
local lbMeta = meta.lightbox
if lbMeta ~= nil and type(lbMeta) == 'table' then
if lbMeta[1] ~= nil then
if lbMeta[1]['text'] == "auto" then
auto = true
end
elseif lbMeta.match ~= nil and pandoc.utils.stringify(lbMeta.match) == 'auto' then
auto = true
elseif lbMeta == true then
auto = true
end
end
end,
-- Find images that are already within links
-- we'll use this to filter out these images if
-- the most is auto
Link = function(linkEl)
pandoc.walk_inline(linkEl, {
Image = function(imageEl)
imagesWithinLinks[#imagesWithinLinks + 1] = imageEl
end
})
end
},{
Div = function(div)
if div.classes:includes("cell") and div.attributes["lightbox"] ~= nil then
meta = quarto.json.decode(div.attributes["lightbox"])
local imgCount=0
div = div:walk({
Image = function(imgEl)
imgCount = imgCount + 1
if (type(meta) == "table" and meta[kNoLightboxClass] == true) or meta == false then
imgEl.classes:insert(kNoLightboxClass)
else
if not auto and ((type(meta) == "table" and not meta[kNoLightboxClass]) or meta == true) then
imgEl.classes:insert(kLightboxClass)
end
if (type(meta) == "table") then
if meta.group then
imgEl.attr.attributes.group = meta.group or imgEl.attr.attributes.group
end
for _, v in next, kForwardedAttr do
if type(meta[v]) == "table" and #meta[v] > 1 then
-- if list attributes it should be one per plot
if imgCount > #meta[v] then
quarto.log.warning("More plots than '" .. v .. "' passed in YAML chunk options.")
else
attrLb = meta[v][imgCount]
end
else
-- Otherwise reuse the single attributes
attrLb = meta[v]
end
imgEl.attr.attributes[v] = attrLb or imgEl.attr.attributes[v]
end
end
end
return imgEl
end
})
div.attributes["lightbox"] = nil
end
return div
end
},
{
Image = function(imgEl)
if quarto.doc.is_format("html:js") then
local isAlreadyLinked = imagesWithinLinks:includes(imgEl)
if (not isAlreadyLinked and auto and not imgEl.classes:includes(kNoLightboxClass))
or imgEl.classes:includes('lightbox') then
-- note that we need to include the dependency for lightbox
needsLightbox = true
imgCount = imgCount + 1

-- remove the class from the image
imgEl.attr.classes = imgEl.attr.classes:filter(function(clz)
return clz ~= kLightboxClass
end)

-- attributes for the link
local linkAttributes = {}

-- mark this image as a lightbox target
linkAttributes.class = kLightboxClass

-- get the alt text from image and use that as title
local title = nil
if imgEl.caption ~= nil and #imgEl.caption > 0 then
linkAttributes.title = pandoc.utils.stringify(imgEl.caption)
elseif imgEl.attributes['fig-alt'] ~= nil and #imgEl.attributes['fig-alt'] > 0 then
linkAttributes.title = pandoc.utils.stringify(imgEl.attributes['fig-alt'])
end

-- move a group attribute to the link, if present
if imgEl.attr.attributes.group ~= nil then
linkAttributes.gallery = imgEl.attr.attributes.group
imgEl.attr.attributes.group = nil
else
linkAttributes.gallery = kGalleryPrefix .. imgCount
end

-- forward any other known attributes
for i, v in ipairs(kForwardedAttr) do
if imgEl.attr.attributes[v] ~= nil then
-- forward the attribute
linkAttributes[v] = readAttrValue(imgEl, v)

-- clear the attribute
imgEl.attr.attributes[v] = nil
end

-- clear the title
if (imgEl.title == 'fig:') then
imgEl.title = ""
end

end

-- wrap decorated images in a link with appropriate attrs
local link = pandoc.Link({imgEl}, imgEl.src, nil, linkAttributes)
return link
end
end
end,
Meta = function(meta)
-- If we discovered lightbox-able images
-- we need to include the dependencies
if needsLightbox then
-- add the dependency
quarto.doc.add_html_dependency({
name = 'glightbox',
scripts = {'resources/js/glightbox.min.js'},
stylesheets = {'resources/css/glightbox.min.css', 'lightbox.css'}
})

-- read lightbox options
local lbMeta = meta.lightbox
local lbOptions = {}
local readEffect = function(el)
local val = pandoc.utils.stringify(el)
if val == "fade" or val == "zoom" or val == "none" then
return val
else
error("Invalid effect " + val)
end
end

-- permitted options include:
-- lightbox:
-- effect: zoom | fade | none
-- desc-position: top | bottom | left |right
-- loop: true | false
-- class: <class-name>
local effect = "zoom"
local descPosition = "bottom"
local loop = true
local skin = nil

-- The selector controls which elements are targeted.
-- currently, it always targets .lightbox elements
-- and there is no way for the user to change this
local selector = "." .. kLightboxClass

if lbMeta ~= nil and type(lbMeta) == 'table' then
if lbMeta.effect ~= nil then
effect = readEffect(lbMeta.effect)
end

if lbMeta['desc-position'] ~= nil then
descPosition = pandoc.utils.stringify(lbMeta['desc-position'])
end

if lbMeta['css-class'] ~= nil then
skin = pandoc.utils.stringify(lbMeta['css-class'])
end

if lbMeta.loop ~= nil then
loop = lbMeta.loop
end
end

-- Generate the options to configure lightbox
local options = {
selector = selector,
closeEffect = effect,
openEffect = effect,
descPosition = descPosition,
loop = loop,
}
if skin ~= nil then
options.skin = skin
end
local optionsJson = quarto.json.encode(options)

-- generate the initialization script with the correct options
local scriptTag = "<script>var lightboxQuarto = GLightbox(" .. optionsJson .. ");</script>"

-- inject the rendering code
quarto.doc.include_text("after-body", scriptTag)

end
end
}}
Loading

0 comments on commit 2a44e45

Please sign in to comment.