/
assetsPlugin.ts
82 lines (75 loc) · 2.59 KB
/
assetsPlugin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import type { PluginWithOptions } from 'markdown-it'
import type { RenderRule } from 'markdown-it/lib/renderer.js'
import type { MarkdownEnv } from '../../types.js'
import { resolveLink } from './resolveLink.js'
export interface AssetsPluginOptions {
/**
* Prefix to add to relative assets links
*/
relativePathPrefix?: string
}
/**
* Plugin to handle assets links
*/
export const assetsPlugin: PluginWithOptions<AssetsPluginOptions> = (
md,
{ relativePathPrefix = '@source' }: AssetsPluginOptions = {}
) => {
// wrap raw image renderer rule
const rawImageRule = md.renderer.rules.image!
md.renderer.rules.image = (tokens, idx, options, env: MarkdownEnv, self) => {
const token = tokens[idx]
// get the image link
const link = token.attrGet('src')
if (link) {
// replace the original link with resolved link
token.attrSet('src', resolveLink(link, relativePathPrefix, env))
}
return rawImageRule(tokens, idx, options, env, self)
}
// wrap raw html renderer rule
const createHtmlRule =
(rawHtmlRule: RenderRule): RenderRule =>
(tokens, idx, options, env: MarkdownEnv, self) => {
// replace the original link with resolved link
tokens[idx].content = tokens[idx].content
// handle src
.replace(
/(<img\b.*?src=)(['"])([^\2]*?)\2/gs,
(_, prefix: string, quote: string, src: string) =>
`${prefix}${quote}${resolveLink(
src.trim(),
relativePathPrefix,
env,
true
)}${quote}`
)
// handle srcset
.replace(
/(<img\b.*?srcset=)(['"])([^\2]*?)\2/gs,
(_, prefix: string, quote: string, srcset: string) =>
`${prefix}${quote}${srcset
.split(',')
.map((item) =>
item
.trim()
.replace(
/^([^ ]*?)([ \n].*)?$/,
(_, url, descriptor = '') =>
`${resolveLink(
url.trim(),
relativePathPrefix,
env,
true
)}${descriptor.replace(/[ \n]+/g, ' ').trimEnd()}`
)
)
.join(', ')}${quote}`
)
return rawHtmlRule(tokens, idx, options, env, self)
}
const rawHtmlBlockRule = md.renderer.rules.html_block!
const rawHtmlInlineRule = md.renderer.rules.html_inline!
md.renderer.rules.html_block = createHtmlRule(rawHtmlBlockRule)
md.renderer.rules.html_inline = createHtmlRule(rawHtmlInlineRule)
}