Skip to content

Commit 6d75e99

Browse files
committed
feat: add skipFootnoteLike option to inline span
Adds a new option to mdc_inline_span that, when enabled, skips footnote-like syntax [^...] to avoid conflicts with footnote plugins (e.g. markdown-it-footnote). By default, the option is false to preserve backward compatibility. Usage: md.use(MarkdownItMdc, { syntax: { inlineSpan: { skipFootnoteLike: true } } }) Fixes compatibility with slidev and other tools using footnotes alongside Comark/MDC syntax.
1 parent c49f0f4 commit 6d75e99

5 files changed

Lines changed: 51 additions & 6 deletions

File tree

src/index.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type MarkdownIt from 'markdown-it'
22
import { MarkdownItMdcBlock } from './syntax/block'
33
import { MarkdownItInlineComponent } from './syntax/inline-component'
44
import { MarkdownItInlineProps } from './syntax/inline-props'
5-
import { MarkdownItInlineSpan } from './syntax/inline-span'
5+
import { MarkdownItInlineSpan, type MdcInlineSpanOptions } from './syntax/inline-span'
66

77
export interface MarkdownItMdcOptions {
88
/**
@@ -26,10 +26,12 @@ export interface MarkdownItMdcOptions {
2626
/**
2727
* Enable inline span syntax.
2828
*
29+
* Pass `true` to enable with defaults, or pass an object to configure.
30+
*
2931
* @see https://content.nuxtjs.org/guide/writing/mdc#inline-span
3032
* @default true
3133
*/
32-
inlineSpan?: boolean
34+
inlineSpan?: boolean | MdcInlineSpanOptions
3335
/**
3436
* Enable inline component syntax.
3537
*
@@ -54,8 +56,12 @@ const MarkdownItMdc: MarkdownIt.PluginWithOptions<MarkdownItMdcOptions> = (md, o
5456
if (inlineProps)
5557
md.use(MarkdownItInlineProps)
5658

57-
if (inlineSpan)
58-
md.use(MarkdownItInlineSpan)
59+
if (inlineSpan) {
60+
const spanOptions = typeof inlineSpan === 'object'
61+
? inlineSpan
62+
: {}
63+
md.use(MarkdownItInlineSpan, spanOptions)
64+
}
5965

6066
if (inlineComponent)
6167
md.use(MarkdownItInlineComponent)

src/syntax/inline-span.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
11
import type MarkdownIt from 'markdown-it'
22

33
export interface MdcInlineSpanOptions {
4-
4+
/**
5+
* Skip footnote-like syntax `[^...]` to avoid conflicts with footnote plugins.
6+
*
7+
* @default false
8+
*/
9+
skipFootnoteLike?: boolean
510
}
611

7-
export const MarkdownItInlineSpan: MarkdownIt.PluginWithOptions<MdcInlineSpanOptions> = (md) => {
12+
export const MarkdownItInlineSpan: MarkdownIt.PluginWithOptions<MdcInlineSpanOptions> = (md, options = {}) => {
13+
const { skipFootnoteLike = false } = options
14+
815
md.inline.ruler.before('link', 'mdc_inline_span', (state, silent) => {
916
const start = state.pos
1017
const char = state.src[start]
1118

1219
if (char !== '[')
1320
return false
1421

22+
if (skipFootnoteLike && state.src[start + 1] === '^')
23+
return false
24+
1525
let index = start + 1
1626
let depth = 0
1727
while (index < state.src.length) {

test/inline-span.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import MarkdownIt from 'markdown-it'
2+
import { describe, expect, it } from 'vitest'
3+
import { MarkdownItInlineSpan } from '../src/syntax/inline-span'
4+
5+
describe('mdc inline span with skipFootnoteLike option', () => {
6+
it('should treat [^note] as span by default', () => {
7+
const md = new MarkdownIt({ html: true })
8+
md.use(MarkdownItInlineSpan)
9+
expect(md.renderInline('Test[^note]'))
10+
.toBe('Test<span>^note</span>')
11+
})
12+
13+
it('should skip [^note] when skipFootnoteLike is true', () => {
14+
const md = new MarkdownIt({ html: true })
15+
md.use(MarkdownItInlineSpan, { skipFootnoteLike: true })
16+
expect(md.renderInline('Test[^note]'))
17+
.toBe('Test[^note]')
18+
})
19+
20+
it('should still render normal span when skipFootnoteLike is true', () => {
21+
const md = new MarkdownIt({ html: true })
22+
md.use(MarkdownItInlineSpan, { skipFootnoteLike: true })
23+
expect(md.renderInline('[^note] and [Span]'))
24+
.toBe('[^note] and <span>Span</span>')
25+
})
26+
})

test/input/8.inline-span.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ Hello [World]{.bg-blue-500}!
55
Hello [World\] Yes]!
66

77
Hello [World]{style=""}!
8+
9+
Test[^note]

test/output/8.inline-span.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
<p>Hello <span class="bg-blue-500">World</span>!</p>
33
<p>Hello <span>World] Yes</span>!</p>
44
<p>Hello <span style="">World</span>!</p>
5+
<p>Test<span>^note</span></p>

0 commit comments

Comments
 (0)