Path: blob/main/tests/docs/extensions/basic/_extensions/quarto-ext/lightbox/lightbox.lua
3571 views
-- whether we're automatically lightboxing1local auto = false23-- whether we need lightbox dependencies added4local needsLightbox = false56-- a counter used to ensure each image is in its own gallery7local imgCount = 089-- attributes to forward from the image to the newly created link10local kForwardedAttr = {11"title", "description", "desc-position",12"type", "effect", "width", "height", "zoomable", "draggable"13}1415local kLightboxClass = "lightbox"16local kNoLightboxClass = "nolightbox"17local kGalleryPrefix = "quarto-lightbox-gallery-"1819-- A list of images already within links that we can use to filter20local imagesWithinLinks = pandoc.List({})2122return {23{24Meta = function(meta)2526-- If the mode is auto, we need go ahead and27-- run if there are any images (ideally we would)28-- filter to images in the body, but that can be29-- left for future me to deal with30-- supports:31-- lightbox: auto32-- or33-- lightbox:34-- match: auto35local lbMeta = meta.lightbox36if lbMeta ~= nil and type(lbMeta) == 'table' then37lbMeta = lbMeta --[[@as any]]38if lbMeta[1] ~= nil then39if lbMeta[1].text == "auto" then40auto = true41end42elseif lbMeta.match ~= nil and pandoc.utils.stringify(lbMeta.match) == 'auto' then43auto = true44elseif lbMeta == true then45auto = true46end47end48end,49-- Find images that are already within links50-- we'll use this to filter out these images if51-- the most is auto52Link = function(linkEl)53pandoc.walk_inline(linkEl, {54Image = function(imageEl)55imagesWithinLinks[#imagesWithinLinks + 1] = imageEl56end57})58end59},60{61Image = function(imgEl)62if quarto.doc.isFormat("html:js") then63local isAlreadyLinked = imagesWithinLinks:includes(imgEl)64if (not isAlreadyLinked and auto and not imgEl.classes:includes(kNoLightboxClass))65or imgEl.classes:includes('lightbox') then66-- note that we need to include the dependency for lightbox67needsLightbox = true68imgCount = imgCount + 16970-- remove the class from the image71imgEl.attr.classes = imgEl.attr.classes:filter(function(clz)72return clz ~= kLightboxClass73end)7475-- attributes for the link76local linkAttributes = {}7778-- mark this image as a lightbox target79linkAttributes.class = kLightboxClass8081-- get the alt text from image and use that as title82local title = nil83if imgEl.caption ~= nil and #imgEl.caption > 0 then84linkAttributes.title = pandoc.utils.stringify(imgEl.caption)85end8687-- move a group attribute to the link, if present88if imgEl.attr.attributes.group ~= nil then89linkAttributes.gallery = imgEl.attr.attributes.group90imgEl.attr.attributes.group = nil91else92linkAttributes.gallery = kGalleryPrefix .. imgCount93end9495-- forward any other known attributes96for i, v in ipairs(kForwardedAttr) do97if imgEl.attr.attributes[v] ~= nil then98-- forward the attribute99linkAttributes[v] = imgEl.attr.attributes[v]100101-- clear the attribute102imgEl.attr.attributes[v] = nil103end104end105106-- wrap decorated images in a link with appropriate attrs107local link = pandoc.Link({imgEl}, imgEl.src, nil, linkAttributes)108return link109end110end111end,112Meta = function(meta)113-- If we discovered lightbox-able images114-- we need to include the dependencies115if needsLightbox then116-- add the dependency117quarto.doc.addHtmlDependency({118name = 'glightbox',119scripts = {'resources/js/glightbox.min.js'},120stylesheets = {'resources/css/glightbox.min.css', 'lightbox.css'}121})122123-- read lightbox options124local lbMeta = meta.lightbox125local lbOptions = {}126local readEffect = function(el)127local val = pandoc.utils.stringify(el)128if val == "fade" or val == "zoom" or val == "none" then129return val130else131error("Invalid effect " + val)132end133end134135-- permitted options include:136-- lightbox:137-- effect: zoom | fade | none138-- desc-position: top | bottom | left |right139-- loop: true | false140-- class: <class-name>141local effect = "zoom"142local descPosition = "bottom"143local loop = true144local skin = nil145146-- The selector controls which elements are targeted.147-- currently, it always targets .lightbox elements148-- and there is no way for the user to change this149local selector = "." .. kLightboxClass150151if lbMeta ~= nil and type(lbMeta) == 'table' then152if lbMeta.effect ~= nil then153effect = readEffect(lbMeta.effect)154end155156if lbMeta['desc-position'] ~= nil then157descPosition = pandoc.utils.stringify(lbMeta['desc-position'])158end159160if lbMeta['css-class'] ~= nil then161skin = pandoc.utils.stringify(lbMeta['css-class'])162end163164if lbMeta.loop ~= nil then165loop = lbMeta.loop166end167end168169-- Generate the options to configure lightbox170local options = {171selector = selector,172closeEffect = effect,173openEffect = effect,174descPosition = descPosition,175loop = loop,176}177if skin ~= nil then178options.skin = skin179end180local optionsJson = quarto.json.encode(options)181182-- generate the initialization script with the correct options183local scriptTag = "<script>var lightboxQuarto = GLightbox(" .. optionsJson .. ");</script>"184185-- inject the rendering code186quarto.doc.includeText("after-body", scriptTag)187188end189end190}}191192193