Path: blob/main/src/resources/extensions/quarto/kbd/kbd.lua
12923 views
-- todo: i18n :(1return {2['kbd'] = function(args, kwargs, meta)3local function get_osname(v)4if v == "win" then return "windows" end5if v == "mac" then return "mac" end6if v == "linux" then return "linux" end7end89-- Extract and validate mode kwarg10local mode = kwargs["mode"]11if mode ~= nil then12mode = pandoc.utils.stringify(mode)13kwargs["mode"] = nil14if mode == "" then15mode = nil16elseif mode ~= "plain" then17return quarto.shortcode.error_output("kbd", "unknown mode: " .. mode .. ", supported modes are: plain", "inline")18else19-- plain mode requires a positional argument20if #args == 0 then21return quarto.shortcode.error_output("kbd", "plain mode requires a positional argument", "inline")22end23-- plain mode doesn't accept OS kwargs24for k, _ in pairs(kwargs) do25return quarto.shortcode.error_output("kbd", "plain mode does not accept OS-specific arguments", "inline")26end27end28end2930if quarto.doc.is_format("html:js") then31quarto.doc.add_html_dependency({32name = 'kbd',33scripts = { 'resources/kbd.js' },34stylesheets = { 'resources/kbd.css' }35})36if mode == "plain" then37local text = pandoc.utils.stringify(args[1])38return pandoc.RawInline('html', '<kbd data-mode="plain" class="kbd">' .. text .. '</kbd>')39end40local kwargs_strs = {}41local title_strs = {}42for k, v in pairs(kwargs) do43local osname = get_osname(k)44if osname == nil then45quarto.log.warning("unknown os name in kbd shortcode: " .. k .. ", supported names are: win, mac, linux")46return quarto.shortcode.error_output("kbd", "unknown os name: " .. k, "inline")47end48table.insert(kwargs_strs, string.format('data-%s="%s"', osname, pandoc.utils.stringify(v)))49table.insert(title_strs, osname .. ': ' .. pandoc.utils.stringify(v))50end51table.sort(kwargs_strs) -- sort so that the output is deterministic52local kwargs_str = table.concat(kwargs_strs)5354local default_arg_str55if #args == 0 then56for k, v in pairs(kwargs) do57default_arg_str = pandoc.utils.stringify(v)58break59end6061default_arg_str = ""62else63default_arg_str = pandoc.utils.stringify(args[1])64table.insert(title_strs, default_arg_str)65end66table.sort(title_strs) -- sort so that the output is deterministic67local title_str = table.concat(title_strs, ', ')68if title_str == "" then69title_str = default_arg_str70end71return pandoc.RawInline('html', '<kbd title="' .. title_str .. '" aria-hidden="true" ' .. kwargs_str .. '>' .. default_arg_str .. '</kbd><span class="visually-hidden">' .. default_arg_str .. '</span>')72elseif quarto.doc.isFormat("asciidoc") then73if args and #args == 1 then74-- https://docs.asciidoctor.org/asciidoc/latest/macros/keyboard-macro/7576-- get the 'first' kbd shortcut as we can only produce one shortcut in asciidoc77local shortcutText = pandoc.utils.stringify(args[1]):gsub('-', '+')7879-- from the docs:80-- If the last key is a backslash (\), it must be followed by a space.81-- Without this space, the processor will not recognize the macro.82-- If one of the keys is a closing square bracket (]), it must be preceded by a backslash.83-- Without the backslash escape, the macro will end prematurely.8485if shortcutText:sub(-1) == "\\" then86shortcutText = shortcutText .. " "87end88if shortcutText:find("]") then89shortcutText = shortcutText:gsub("]", "\\]")90end9192return pandoc.RawInline("asciidoc", "kbd:[" .. shortcutText .. "]")93else94return quarto.shortcode.error_output("kbd", "kbd only supports one positional argument", "inline")95end96else97-- example shortcodes98-- {{< kbd Shift-Ctrl-P >}}99-- {{< kbd Shift-Ctrl-P mac=Shift-Command-P >}}100-- {{< kbd mac=Shift-Command-P win=Shift-Control-S linux=Shift-Ctrl-S >}}101if mode == "plain" then102return pandoc.Code(pandoc.utils.stringify(args[1]))103end104local result = {};105local n_kwargs = 0106for k, v in pairs(kwargs) do107n_kwargs = n_kwargs + 1108end109if #args == 1 then110table.insert(result, pandoc.Code(pandoc.utils.stringify(args[1])))111if n_kwargs > 0 then112table.insert(result, pandoc.Str(' ('))113for k, v in pairs(kwargs) do114table.insert(result, pandoc.Str(get_osname(k)))115table.insert(result, pandoc.Str(': '))116table.insert(result, pandoc.Code(pandoc.utils.stringify(v)))117n_kwargs = n_kwargs - 1118if n_kwargs > 0 then119table.insert(result, pandoc.Str('; '))120end121end122table.insert(result, pandoc.Str(')'))123end124else125-- all kwargs126if n_kwargs == 0 then127-- luacov: disable128error("kbd requires at least one argument")129-- luacov: enable130else131for k, v in pairs(kwargs) do132table.insert(result, pandoc.Code(pandoc.utils.stringify(v)))133table.insert(result, pandoc.Str(' ('))134table.insert(result, pandoc.Str(get_osname(k)))135table.insert(result, pandoc.Str(')'))136n_kwargs = n_kwargs - 1137if n_kwargs > 0 then138table.insert(result, pandoc.Str(', '))139end140end141end142end143return result144end145end146}147148149