summaryrefslogtreecommitdiff
path: root/_extensions/dragonstyle/unsplash/unsplash.lua
diff options
context:
space:
mode:
Diffstat (limited to '_extensions/dragonstyle/unsplash/unsplash.lua')
-rw-r--r--_extensions/dragonstyle/unsplash/unsplash.lua193
1 files changed, 193 insertions, 0 deletions
diff --git a/_extensions/dragonstyle/unsplash/unsplash.lua b/_extensions/dragonstyle/unsplash/unsplash.lua
new file mode 100644
index 0000000..fd87ab2
--- /dev/null
+++ b/_extensions/dragonstyle/unsplash/unsplash.lua
@@ -0,0 +1,193 @@
+
+local mimeImgExts = {
+ ["image/jpeg"]="jpg",
+ ["image/gif"]="gif",
+ ["image/vnd.microsoft.icon"]="ico",
+ ["image/avif"]="avif",
+ ["image/bmp"]="bmp",
+ ["image/png"]="png",
+ ["image/svg+xml"]="svg",
+ ["image/tiff"]="tif",
+ ["image/webp"]="webp",
+}
+
+local function file_exists(name)
+ local f = io.open(name, 'r')
+ if f ~= nil then
+ io.close(f)
+ return true
+ else
+ return false
+ end
+end
+
+local function write_file(path, contents, mode)
+ pandoc.system.make_directory(pandoc.path.directory(path), true)
+ mode = mode or "a"
+ local file = io.open(path, mode)
+ if file then
+ file:write(contents)
+ file:close()
+ return true
+ else
+ return false
+ end
+end
+
+
+
+
+return {
+ ['unsplash'] = function(args, kwargs, meta)
+
+
+ -- positional == keywords
+ -- {{< unsplash cat >}}
+ -- {{< unsplash keywords="cats" height="300" width="300"}}
+
+ -- TODO: use the real api to download a copy of the image using rest
+ -- TODO: ping the download url
+ -- TODO: Generate a stable name for the image
+ -- TODO: Make this a format resource instead of media bag, so images become stable
+ -- TODO: generate more complete information from REST endpoint to credit author
+
+ local height = nil
+ local width = nil
+ local keywords = nil
+ local classes = nil
+ local float = nil
+
+ -- the filename
+ local filename
+ if args[1] ~= nil then
+ filename = pandoc.utils.stringify(args[1])
+ local stem = pandoc.path.split_extension(pandoc.path.filename(filename))
+ keywords = stem
+ end
+
+ -- height
+ if kwargs['height'] ~= nil and #kwargs['height'] > 0 then
+ height = pandoc.utils.stringify(kwargs['height'])
+ end
+
+ -- width
+ if kwargs['width'] ~= nil and #kwargs['width'] > 0 then
+ width = pandoc.utils.stringify(kwargs['width'])
+ end
+
+ -- keywords
+ if kwargs['keywords'] ~= nil and #kwargs['keywords'] > 0 then
+ keywords = pandoc.utils.stringify(kwargs['keywords'])
+ end
+
+ -- classes
+ if kwargs['class'] ~= nil and #kwargs['class'] > 0 then
+ classes = pandoc.utils.stringify(kwargs['class'])
+ end
+
+ -- classes
+ if kwargs['float'] ~= nil and #kwargs['float'] > 0 then
+ float = pandoc.utils.stringify(kwargs['float'])
+ end
+
+
+ -- form the unsplash URL that will be used
+ local url = "https://source.unsplash.com/random"
+ if width and height then
+ url = url .. "/" .. tostring(width) .. '×' .. tostring(height)
+ end
+ if keywords ~= nil then
+ url = url .. '/?' .. keywords
+ end
+
+ -- deal with the height and width
+
+ local imgContainer = function (imgEl)
+
+ -- HTML formats use a container to implement sizing, so
+ -- apply classes and so on to that container
+ if quarto.doc.is_format("html") then
+
+
+ quarto.doc.add_html_dependency({
+ name = "unsplash-styles",
+ version = "1.0.0",
+ stylesheets = {"style.css"}
+ })
+
+ local style = ""
+ if height then
+ style = style .. 'height: ' .. height .. '; '
+ end
+ if width then
+ style = style .. 'width: ' .. width .. '; '
+ end
+
+ local divAttrRaw = {}
+ if style ~= "" then
+ divAttrRaw['style'] = style
+ end
+
+ local clz = pandoc.List({'unsplash-container'})
+ if float then
+ clz:insert('float-' .. float)
+ end
+
+ if classes ~= nil then
+ for token in string.gmatch(classes, "[^%s]+") do
+ clz:insert(token)
+ end
+ end
+
+ local divAttr = pandoc.Attr("", clz, divAttrRaw)
+ local div = pandoc.Div(imgEl, divAttr)
+
+ return div
+
+ else
+
+ -- Non-HTML formats just return the raw image with
+ -- any options set on that
+
+ if height then
+ imgEl.attr.attributes['height'] = height
+ end
+ if width then
+ imgEl.attr.attributes['width'] = width
+ end
+
+ if classes ~= nil then
+ for clz in string.gmatch(classes, "[^%s]+") do
+ imgEl.attr.classes:insert(clz)
+ end
+ end
+
+ return imgEl
+
+ end
+ end
+
+ if filename ~= nil and file_exists(filename) then
+ return imgContainer(pandoc.Image("", filename))
+ elseif filename ~= nil then
+ -- read the image
+ local _imgMt, imgContents = pandoc.mediabag.fetch(url)
+ write_file(filename, imgContents, "wb")
+ return imgContainer(pandoc.Image("", filename))
+ else
+ -- read the image
+ local imgMt, imgContents = pandoc.mediabag.fetch(url)
+
+ -- place it in media bag and link to it
+ if imgContents ~= nil then
+ local tmpFileName = pandoc.path.filename(os.tmpname()) ..'.' .. mimeImgExts[imgMt]
+ pandoc.mediabag.insert(tmpFileName, imgMt, imgContents)
+ return imgContainer(pandoc.Image("", tmpFileName))
+ end
+ end
+
+
+ end
+}
+
+