File size: 2,699 Bytes
0cb2777
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
-- for development:
local p = quarto.log.warning

---Format string like in bash or python,
---e.g. f('Hello ${one}', {one = 'world'})
---@param s string The string to format
---@param kwargs {[string]: string} A table with key-value replacemen pairs
---@return string
local function f(s, kwargs)
  return (s:gsub('($%b{})', function(w) return kwargs[w:sub(3, -2)] or w end))
end


---Merge user provided options with defaults
---@param userOptions table
---@return string JSON string to pass to molstar
local function mergeOptions(url, userOptions)
  local defaultOptions = {
    text = url,
    width = 128,
    height = 128,
    colorDark = "#000000",
    colorLight = "#ffffff",
  }
  if userOptions == nil then
    return quarto.json.encode(defaultOptions)
  end

  for k, v in pairs(userOptions) do
    local value = pandoc.utils.stringify(v)
    if value == 'true' then value = true end
    if value == 'false' then value = false end
    defaultOptions[k] = value
  end

  return quarto.json.encode(defaultOptions)
end


---@return string
local function wrapInlineDiv(options)
  return [[
<div id="${id}" class="qrcode"></div>
<script type="text/javascript">
var qrcode = new QRCode("${id}", ]]
      .. options .. [[);
</script>
    ]]
end

---@return string
local function wrapInlineTex(url, opts)
  return [[
\qrcode[]] .. opts .. [[]{]] .. url .. [[}
    ]]
end

return {
  ['qrcode'] = function(args, kwargs, _)
    if quarto.doc.is_format("html:js") then
      quarto.doc.add_html_dependency {
        name = 'qrcodejs',
        version = 'v1.0.0',
        scripts = { './assets/qrcode.js' },
      }
      local url = pandoc.utils.stringify(args[1])
      local id = 'qrcode'
      local maybeId = args[2]
      if maybeId ~= nil then
        id = pandoc.utils.stringify(maybeId)
      end
      local options = mergeOptions(url, kwargs)
      local text = wrapInlineDiv(options)
      return pandoc.RawBlock(
        'html',
        f(text, { id = id })
      )
    elseif quarto.doc.is_format("pdf") then
      quarto.doc.use_latex_package("qrcode")
      local url = pandoc.utils.stringify(args[1])
      local opts = ""
      for k, v in pairs(kwargs) do
        if string.match(k, "^pdf") then
          k = string.sub(k, 4)
          opts = opts .. k .. "=" .. v .. ", "
        end
      end
      for _, v in ipairs(args) do
        if string.match(v, "^pdf") then
          v = string.sub(v, 4)
          opts = opts .. v .. ", "
        end
      end
      if string.len(opts) then
        opts = string.sub(opts, 1, string.len(opts) - 2)
      end
      local text = wrapInlineTex(url, opts)
      return pandoc.RawBlock(
        'tex',
        text
      )
    end
  end,
}