We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
1 parent 074f7f0 commit 54fc12fCopy full SHA for 54fc12f
README.md
@@ -13,9 +13,9 @@ md.use(kbd);
13
14
This plugin can also be used together with [`markdown-it-attrs`](https://github.com/arve0/markdown-it-attrs/).
15
16
-## Parsing notes
+## Syntax notes
17
18
The end tag `]]` must be on the same line as the start tag `[[`.
19
20
-The combinations “`[[`” and “`]]`” are not allowed within keystroke tags.
21
-If you need to use them, use the HTML escape sequence “`[[`” for “`[[`” or “`]]`” for “`]]`”.
+The characters “`[`” and “`]`” are not allowed within keystroke tags.
+If you need to use them, escape them with a backslash (i.e. `\[` or `\]`) or use HTML escape sequences (`[` for `[` or `]` for `]`).
src/index.ts
@@ -3,6 +3,7 @@ import StateInline from 'markdown-it/lib/rules_inline/state_inline'
3
4
const MARKER_OPEN = '['
5
const MARKER_CLOSE = ']'
6
+const ESCAPE_CHARACTER = '\\'
7
const TAG = 'kbd'
8
9
/*
@@ -26,25 +27,31 @@ function tokenize(state: StateInline, silent: boolean) {
26
27
// Find the end sequence
28
let openTagCount = 1
29
let end = -1
- nextChar = state.src.charAt(start + 2)
30
+ let skipNext = false
31
for (let i = start + 1; i < max && end === -1; i++) {
- momChar = state.src.charAt(i) // do not copy from nextChar because we sometimes skip over indices
32
+ momChar = nextChar
33
nextChar = state.src.charAt(i + 1)
34
+ if (skipNext) {
35
+ skipNext = false
36
+ continue
37
+ }
38
if (momChar === MARKER_CLOSE && nextChar === MARKER_CLOSE) {
39
openTagCount -= 1
40
if (openTagCount == 0) {
41
// Found the end!
42
end = i
43
}
44
// Skip second marker char, it is already counted.
- i += 1
45
+ skipNext = true
46
} else if (momChar === MARKER_OPEN && nextChar === MARKER_OPEN) {
47
openTagCount += 1
48
49
50
} else if (momChar === '\n') {
51
// Found end of line before the end sequence. Thus, ignore our start sequence!
52
return false
53
+ } else if (momChar === ESCAPE_CHARACTER) {
54
55
56
57
test/test.ts
@@ -28,6 +28,15 @@ describe('markdown-it-kbd', () => {
`))
})
+ it.each([
+ ['[[\\[]]', '<kbd>[</kbd>'],
+ ['[[\\]]]', '<kbd>]</kbd>'],
+ ['[[\\[\\[]]', '<kbd>[[</kbd>'],
+ ['[[\\]\\]]]', '<kbd>]]</kbd>']
+ ])('supports escaped delimiters: %s', (input, expected) => {
+ expect(md.render(input)).toBe(`<p>${expected}</p>\n`)
+ })
+
it('supports deep nesting and markup in nested tags', () => {
expect(md.render(trimmed(`
[[[[[[Shift]]\`+\`[[_long[[x]]_]]]]-Ctrl]]+[[F4]]
@@ -73,7 +82,8 @@ describe('markdown-it-kbd', () => {
73
82
['[[[x]]', '[<kbd>x</kbd>'],
74
83
['[[[x]]]', '[<kbd>x</kbd>]'],
75
84
['[[*test*', '[[<em>test</em>'],
76
- ['[[[[Shift]]+[[F3]]]', '[[<kbd>Shift</kbd>+<kbd>F3</kbd>]']
85
+ ['[[[[Shift]]+[[F3]]]', '[[<kbd>Shift</kbd>+<kbd>F3</kbd>]'],
86
+ ['[[\\\\]]', '<kbd>\\</kbd>']
77
87
])('renders correctly: %s', (input, expected) => {
78
88
expect(md.render(input)).toBe(`<p>${expected}</p>\n`)
79
89
0 commit comments