Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/src/resources/extensions/quarto/kbd/kbd.lua
12923 views
1
-- todo: i18n :(
2
return {
3
['kbd'] = function(args, kwargs, meta)
4
local function get_osname(v)
5
if v == "win" then return "windows" end
6
if v == "mac" then return "mac" end
7
if v == "linux" then return "linux" end
8
end
9
10
-- Extract and validate mode kwarg
11
local mode = kwargs["mode"]
12
if mode ~= nil then
13
mode = pandoc.utils.stringify(mode)
14
kwargs["mode"] = nil
15
if mode == "" then
16
mode = nil
17
elseif mode ~= "plain" then
18
return quarto.shortcode.error_output("kbd", "unknown mode: " .. mode .. ", supported modes are: plain", "inline")
19
else
20
-- plain mode requires a positional argument
21
if #args == 0 then
22
return quarto.shortcode.error_output("kbd", "plain mode requires a positional argument", "inline")
23
end
24
-- plain mode doesn't accept OS kwargs
25
for k, _ in pairs(kwargs) do
26
return quarto.shortcode.error_output("kbd", "plain mode does not accept OS-specific arguments", "inline")
27
end
28
end
29
end
30
31
if quarto.doc.is_format("html:js") then
32
quarto.doc.add_html_dependency({
33
name = 'kbd',
34
scripts = { 'resources/kbd.js' },
35
stylesheets = { 'resources/kbd.css' }
36
})
37
if mode == "plain" then
38
local text = pandoc.utils.stringify(args[1])
39
return pandoc.RawInline('html', '<kbd data-mode="plain" class="kbd">' .. text .. '</kbd>')
40
end
41
local kwargs_strs = {}
42
local title_strs = {}
43
for k, v in pairs(kwargs) do
44
local osname = get_osname(k)
45
if osname == nil then
46
quarto.log.warning("unknown os name in kbd shortcode: " .. k .. ", supported names are: win, mac, linux")
47
return quarto.shortcode.error_output("kbd", "unknown os name: " .. k, "inline")
48
end
49
table.insert(kwargs_strs, string.format('data-%s="%s"', osname, pandoc.utils.stringify(v)))
50
table.insert(title_strs, osname .. ': ' .. pandoc.utils.stringify(v))
51
end
52
table.sort(kwargs_strs) -- sort so that the output is deterministic
53
local kwargs_str = table.concat(kwargs_strs)
54
55
local default_arg_str
56
if #args == 0 then
57
for k, v in pairs(kwargs) do
58
default_arg_str = pandoc.utils.stringify(v)
59
break
60
end
61
62
default_arg_str = ""
63
else
64
default_arg_str = pandoc.utils.stringify(args[1])
65
table.insert(title_strs, default_arg_str)
66
end
67
table.sort(title_strs) -- sort so that the output is deterministic
68
local title_str = table.concat(title_strs, ', ')
69
if title_str == "" then
70
title_str = default_arg_str
71
end
72
return pandoc.RawInline('html', '<kbd title="' .. title_str .. '" aria-hidden="true" ' .. kwargs_str .. '>' .. default_arg_str .. '</kbd><span class="visually-hidden">' .. default_arg_str .. '</span>')
73
elseif quarto.doc.isFormat("asciidoc") then
74
if args and #args == 1 then
75
-- https://docs.asciidoctor.org/asciidoc/latest/macros/keyboard-macro/
76
77
-- get the 'first' kbd shortcut as we can only produce one shortcut in asciidoc
78
local shortcutText = pandoc.utils.stringify(args[1]):gsub('-', '+')
79
80
-- from the docs:
81
-- If the last key is a backslash (\), it must be followed by a space.
82
-- Without this space, the processor will not recognize the macro.
83
-- If one of the keys is a closing square bracket (]), it must be preceded by a backslash.
84
-- Without the backslash escape, the macro will end prematurely.
85
86
if shortcutText:sub(-1) == "\\" then
87
shortcutText = shortcutText .. " "
88
end
89
if shortcutText:find("]") then
90
shortcutText = shortcutText:gsub("]", "\\]")
91
end
92
93
return pandoc.RawInline("asciidoc", "kbd:[" .. shortcutText .. "]")
94
else
95
return quarto.shortcode.error_output("kbd", "kbd only supports one positional argument", "inline")
96
end
97
else
98
-- example shortcodes
99
-- {{< kbd Shift-Ctrl-P >}}
100
-- {{< kbd Shift-Ctrl-P mac=Shift-Command-P >}}
101
-- {{< kbd mac=Shift-Command-P win=Shift-Control-S linux=Shift-Ctrl-S >}}
102
if mode == "plain" then
103
return pandoc.Code(pandoc.utils.stringify(args[1]))
104
end
105
local result = {};
106
local n_kwargs = 0
107
for k, v in pairs(kwargs) do
108
n_kwargs = n_kwargs + 1
109
end
110
if #args == 1 then
111
table.insert(result, pandoc.Code(pandoc.utils.stringify(args[1])))
112
if n_kwargs > 0 then
113
table.insert(result, pandoc.Str(' ('))
114
for k, v in pairs(kwargs) do
115
table.insert(result, pandoc.Str(get_osname(k)))
116
table.insert(result, pandoc.Str(': '))
117
table.insert(result, pandoc.Code(pandoc.utils.stringify(v)))
118
n_kwargs = n_kwargs - 1
119
if n_kwargs > 0 then
120
table.insert(result, pandoc.Str('; '))
121
end
122
end
123
table.insert(result, pandoc.Str(')'))
124
end
125
else
126
-- all kwargs
127
if n_kwargs == 0 then
128
-- luacov: disable
129
error("kbd requires at least one argument")
130
-- luacov: enable
131
else
132
for k, v in pairs(kwargs) do
133
table.insert(result, pandoc.Code(pandoc.utils.stringify(v)))
134
table.insert(result, pandoc.Str(' ('))
135
table.insert(result, pandoc.Str(get_osname(k)))
136
table.insert(result, pandoc.Str(')'))
137
n_kwargs = n_kwargs - 1
138
if n_kwargs > 0 then
139
table.insert(result, pandoc.Str(', '))
140
end
141
end
142
end
143
end
144
return result
145
end
146
end
147
}
148
149