Skip to content

Commit 51ddf91

Browse files
authored
add support for kbd shortcode. Closes #3384 (#3395)
See https://quarto.org/docs/prerelease/1.3.html for documentation.
1 parent 6978ced commit 51ddf91

File tree

6 files changed

+136
-0
lines changed

6 files changed

+136
-0
lines changed

news/changelog-1.3.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,4 @@
6666
- Add optional `rel` attribute to navigation links ([#3212](https://github.com/quarto-dev/quarto-cli/issues/3212))
6767
- Use the right port when CRI is initialized multiple times ([#3066](https://github.com/quarto-dev/quarto-cli/issues/3066))
6868
- Allow custom themes for giscus ([#3105](https://github.com/quarto-dev/quarto-cli/issues/3105))
69+
- new `kbd` shortcode, to describe keyboard keys ([#3384](https://github.com/quarto-dev/quarto-cli/issues/3384)). See the [pre-release documentation](https://quarto.org/docs/prerelease/1.3.html) for details.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
title: Kbd
2+
author: Posit, PBC
3+
organization: quarto
4+
contributes:
5+
shortcodes:
6+
- kbd.lua
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
-- todo: i18n :(
2+
return {
3+
['kbd'] = function(args, kwargs, meta)
4+
local function 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+
if quarto.doc.is_format("html:js") then
10+
quarto.doc.add_html_dependency({
11+
name = 'kbd',
12+
scripts = { 'resources/kbd.js' },
13+
stylesheets = { 'resources/kbd.css' }
14+
})
15+
local kwargs_strs = {}
16+
for k, v in pairs(kwargs) do
17+
table.insert(kwargs_strs, string.format('data-%s="%s"', osname(k), pandoc.utils.stringify(v)))
18+
end
19+
local kwargs_str = table.concat(kwargs_strs)
20+
21+
local default_arg_str
22+
if #args == 0 then
23+
for k, v in pairs(kwargs) do
24+
default_arg_str = pandoc.utils.stringify(v)
25+
break
26+
end
27+
28+
default_arg_str = ""
29+
else
30+
default_arg_str = pandoc.utils.stringify(args[1])
31+
end
32+
33+
return pandoc.RawInline('html', '<kbd ' .. kwargs_str .. '>' .. default_arg_str .. '</kbd>')
34+
else
35+
-- example shortcodes
36+
-- {{< kbd Shift-Ctrl-P >}}
37+
-- {{< kbd Shift-Ctrl-P mac=Shift-Command-P >}}
38+
-- {{< kbd mac=Shift-Command-P win=Shift-Control-S linux=Shift-Ctrl-S >}}
39+
local result = {};
40+
local n_kwargs = 0
41+
for k, v in pairs(kwargs) do
42+
n_kwargs = n_kwargs + 1
43+
end
44+
if #args == 1 then
45+
table.insert(result, pandoc.Code(pandoc.utils.stringify(args[1])))
46+
if n_kwargs > 0 then
47+
table.insert(result, pandoc.Str(' ('))
48+
for k, v in pairs(kwargs) do
49+
table.insert(result, pandoc.Str(osname(k)))
50+
table.insert(result, pandoc.Str(': '))
51+
table.insert(result, pandoc.Code(pandoc.utils.stringify(v)))
52+
n_kwargs = n_kwargs - 1
53+
if n_kwargs > 0 then
54+
table.insert(result, pandoc.Str('; '))
55+
end
56+
end
57+
table.insert(result, pandoc.Str(')'))
58+
end
59+
else
60+
-- all kwargs
61+
if n_kwargs == 0 then
62+
error("kbd requires at least one argument")
63+
else
64+
for k, v in pairs(kwargs) do
65+
table.insert(result, pandoc.Code(pandoc.utils.stringify(v)))
66+
table.insert(result, pandoc.Str(' ('))
67+
table.insert(result, pandoc.Str(osname(k)))
68+
table.insert(result, pandoc.Str(')'))
69+
n_kwargs = n_kwargs - 1
70+
if n_kwargs > 0 then
71+
table.insert(result, pandoc.Str(', '))
72+
end
73+
end
74+
end
75+
end
76+
return result
77+
end
78+
end
79+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
kbd.kbd {
2+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
(() => {
2+
function guessOS() {
3+
const userAgent = window.navigator.userAgent;
4+
if (userAgent.includes("Mac OS")) {
5+
return {
6+
name: "mac",
7+
};
8+
} else if (userAgent.includes("Windows")) {
9+
return {
10+
name: "win",
11+
};
12+
} else {
13+
return {
14+
name: "linux",
15+
};
16+
}
17+
}
18+
const os = guessOS();
19+
20+
// deno-lint-ignore no-window-prefix
21+
window.addEventListener("DOMContentLoaded", (_) => {
22+
for (const el of Array.from(document.querySelectorAll("kbd"))) {
23+
el.classList.add("kbd");
24+
if (el.dataset[os.name] !== undefined) {
25+
el.innerText = el.dataset[os.name];
26+
}
27+
if (os.name === "mac") {
28+
el.innerText = el.innerText
29+
.replaceAll(/command-?/gi, "⌘")
30+
.replaceAll(/cmd-?/gi, "⌘")
31+
.replaceAll(/shift-?/gi, "⇧")
32+
.replaceAll(/ctrl-?/gi, "⌃")
33+
.replaceAll(/control-?/gi, "⌃")
34+
.replaceAll(/option-?/gi, "⌥");
35+
}
36+
}
37+
});
38+
})();
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
title: test
3+
format:
4+
html: default
5+
pdf: default
6+
---
7+
8+
To foo, press {{< kbd Shift-Ctrl-P >}}. To bar, press {{< kbd Shift-Ctrl-P mac=Shift-Command-P >}}. To baz, press {{< kbd mac=Shift-Command-P win=Shift-Control-S linux=Shift-Ctrl-S >}}.
9+
10+
To foo, press {{< kbd win=Shift-Ctrl-P >}}.

0 commit comments

Comments
 (0)