-
-
Notifications
You must be signed in to change notification settings - Fork 128
/
marp.ts
127 lines (107 loc) · 3.52 KB
/
marp.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { Marpit, Options, ThemeSetPackOptions } from '@marp-team/marpit'
import highlightjs from 'highlight.js'
import postcss, { AcceptedPlugin } from 'postcss'
import defaultTheme from '../themes/default.scss'
import gaiaTheme from '../themes/gaia.scss'
import uncoverTheme from '../themes/uncover.scss'
import * as autoScalingPlugin from './auto-scaling'
import * as customElements from './custom-elements'
import * as emojiPlugin from './emoji/emoji'
import * as htmlPlugin from './html/html'
import * as mathPlugin from './math/math'
import minifyPlugins from './prebundles/postcss-minify-plugins'
import * as scriptPlugin from './script/script'
import * as sizePlugin from './size/size'
export interface MarpOptions extends Options {
emoji?: emojiPlugin.EmojiOptions
html?:
| boolean
| {
[tag: string]:
| string[]
| { [attr: string]: boolean | ((value: string) => string) }
}
markdown?: object
math?: mathPlugin.MathOptions
minifyCSS?: boolean
script?: boolean | scriptPlugin.ScriptOptions
}
export class Marp extends Marpit {
readonly options!: Required<MarpOptions>
static readonly html = { br: [] }
constructor(opts: MarpOptions = {}) {
const mdOpts: Record<string, any> = {
breaks: true,
linkify: true,
highlight: (code, lang, attrs) => this.highlighter(code, lang, attrs),
html: opts.html ?? Marp.html,
...(typeof opts.markdown === 'object' ? opts.markdown : {}),
}
super({
inlineSVG: true,
looseYAML: true,
math: true,
minifyCSS: true,
script: true,
...opts,
emoji: {
shortcode: 'twemoji',
unicode: 'twemoji',
...(opts.emoji || {}),
},
markdown: ['commonmark', mdOpts],
} as MarpOptions)
this.markdown.enable(['table', 'linkify', 'strikethrough'])
this.markdown.linkify.set({ fuzzyLink: false })
if (mdOpts.typographer) {
this.markdown.enable(['replacements', 'smartquotes'])
}
// Theme support
this.themeSet.metaType = Object.freeze({
'auto-scaling': String,
size: Array,
})
this.themeSet.default = this.themeSet.add(defaultTheme)
this.themeSet.add(gaiaTheme)
this.themeSet.add(uncoverTheme)
}
protected applyMarkdownItPlugins(md) {
super.applyMarkdownItPlugins(md)
md.use(htmlPlugin.markdown)
.use(emojiPlugin.markdown)
.use(mathPlugin.markdown)
.use(autoScalingPlugin.markdown)
.use(sizePlugin.markdown)
.use(scriptPlugin.markdown)
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
highlighter(code: string, lang: string, attrs: string): string {
if (lang && highlightjs.getLanguage(lang)) {
return highlightjs.highlight(code, {
language: lang,
ignoreIllegals: true,
}).value
}
return ''
}
protected renderStyle(theme?: string): string {
const original = super.renderStyle(theme)
const postprocessorPlugins: AcceptedPlugin[] = [
customElements.css,
...(this.options.minifyCSS ? minifyPlugins : []),
]
const postprocessor = postcss(postprocessorPlugins)
return postprocessor.process(original).css
}
protected themeSetPackOptions(): ThemeSetPackOptions {
const base = { ...super.themeSetPackOptions() }
const prepend = (css) =>
css && (base.before = `${css}\n${base.before || ''}`)
const { emoji } = this.options
prepend(emojiPlugin.css(emoji))
const mathCss = mathPlugin.css(this)
if (mathCss) prepend(mathCss)
return base
}
}
export default Marp