Files
olehomelchenko.com/vega-lite.lua

76 lines
1.9 KiB
Lua

-- vega-lite.lua
-- A Quarto filter to render vega-lite code blocks using vega-embed
local vegaEmbedIncluded = false
function ensureVegaEmbed()
if not vegaEmbedIncluded then
vegaEmbedIncluded = true
quarto.doc.include_text("in-header", [[
<script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-lite@5"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-embed@6"></script>
]])
end
end
local counter = 0
function CodeBlock(block)
if block.classes:includes('vega-lite') then
ensureVegaEmbed()
counter = counter + 1
local divId = 'vega-viz-' .. counter
-- Get the spec as a string
local spec = block.text
-- Parse options from attributes
local echo = block.attributes['echo']
local codeFold = block.attributes['code-fold']
-- Default to showing code
if echo == nil then echo = "true" end
local result = {}
-- Handle code display
if echo ~= "false" then
local codeBlock = pandoc.CodeBlock(spec, {class = "json"})
if codeFold == "true" or codeFold == "show" then
-- Wrap in collapsible details/summary
local openAttr = ""
if codeFold == "show" then
openAttr = " open"
end
local foldedCode = pandoc.RawBlock('html', string.format([[
<details%s>
<summary>Click to expand code</summary>
]], openAttr))
table.insert(result, foldedCode)
table.insert(result, codeBlock)
table.insert(result, pandoc.RawBlock('html', '</details>'))
else
-- Show code normally
table.insert(result, codeBlock)
end
end
-- Create the HTML output for the visualization
local html = string.format([[
<div id="%s"></div>
<script type="text/javascript">
vegaEmbed('#%s', %s, {"actions": true});
</script>
]], divId, divId, spec)
table.insert(result, pandoc.RawBlock('html', html))
return result
end
end