@@ -2,6 +2,11 @@ import YAML from 'yaml'
2
2
import { ensurePrefix } from '@antfu/utils'
3
3
import type { FrontmatterStyle , SlidevDetectedFeatures , SlidevMarkdown , SlidevPreparserExtension , SourceSlideInfo } from '@slidev/types'
4
4
5
+ export interface SlidevParserOptions {
6
+ noParseYAML ?: boolean
7
+ preserveCR ?: boolean
8
+ }
9
+
5
10
export function stringify ( data : SlidevMarkdown ) {
6
11
return `${ data . slides . map ( stringifySlide ) . join ( '\n' ) . trim ( ) } \n`
7
12
}
@@ -30,7 +35,7 @@ export function prettify(data: SlidevMarkdown) {
30
35
return data
31
36
}
32
37
33
- function matter ( code : string ) {
38
+ function matter ( code : string , options : SlidevParserOptions ) {
34
39
let type : FrontmatterStyle | undefined
35
40
let raw : string | undefined
36
41
@@ -50,13 +55,13 @@ function matter(code: string) {
50
55
} )
51
56
}
52
57
53
- const doc = YAML . parseDocument ( raw || '' )
58
+ const doc = raw && ! options . noParseYAML ? YAML . parseDocument ( raw ) : undefined
54
59
55
60
return {
56
61
type,
57
62
raw,
58
63
doc,
59
- data : doc . toJSON ( ) ,
64
+ data : doc ? .toJSON ( ) ,
60
65
content,
61
66
}
62
67
}
@@ -70,8 +75,8 @@ export function detectFeatures(code: string): SlidevDetectedFeatures {
70
75
}
71
76
}
72
77
73
- export function parseSlide ( raw : string ) : Omit < SourceSlideInfo , 'filepath' | 'index' | 'start' | 'contentStart' | 'end' > {
74
- const matterResult = matter ( raw )
78
+ export function parseSlide ( raw : string , options : SlidevParserOptions = { } ) : Omit < SourceSlideInfo , 'filepath' | 'index' | 'start' | 'contentStart' | 'end' > {
79
+ const matterResult = matter ( raw , options )
75
80
let note : string | undefined
76
81
const frontmatter = matterResult . data || { }
77
82
let content = matterResult . content . trim ( )
@@ -115,8 +120,9 @@ export async function parse(
115
120
markdown : string ,
116
121
filepath : string ,
117
122
extensions ?: SlidevPreparserExtension [ ] ,
123
+ options : SlidevParserOptions = { } ,
118
124
) : Promise < SlidevMarkdown > {
119
- const lines = markdown . split ( / \r ? \n / g)
125
+ const lines = markdown . split ( options . preserveCR ? '\n' : / \r ? \n / g)
120
126
const slides : SourceSlideInfo [ ] = [ ]
121
127
122
128
let start = 0
@@ -127,7 +133,7 @@ export async function parse(
127
133
return
128
134
const raw = lines . slice ( start , end ) . join ( '\n' )
129
135
const slide : SourceSlideInfo = {
130
- ...parseSlide ( raw ) ,
136
+ ...parseSlide ( raw , options ) ,
131
137
filepath,
132
138
index : slides . length ,
133
139
start,
@@ -195,6 +201,74 @@ export async function parse(
195
201
}
196
202
}
197
203
204
+ export function parseSync (
205
+ markdown : string ,
206
+ filepath : string ,
207
+ options : SlidevParserOptions = { } ,
208
+ ) : SlidevMarkdown {
209
+ const lines = markdown . split ( options . preserveCR ? '\n' : / \r ? \n / g)
210
+ const slides : SourceSlideInfo [ ] = [ ]
211
+
212
+ let start = 0
213
+ let contentStart = 0
214
+
215
+ function slice ( end : number ) {
216
+ if ( start === end )
217
+ return
218
+ const raw = lines . slice ( start , end ) . join ( '\n' )
219
+ const slide : SourceSlideInfo = {
220
+ ...parseSlide ( raw , options ) ,
221
+ filepath,
222
+ index : slides . length ,
223
+ start,
224
+ contentStart,
225
+ end,
226
+ }
227
+ slides . push ( slide )
228
+ start = end + 1
229
+ contentStart = end + 1
230
+ }
231
+
232
+ for ( let i = 0 ; i < lines . length ; i ++ ) {
233
+ const line = lines [ i ] . trimEnd ( )
234
+ if ( line . startsWith ( '---' ) ) {
235
+ slice ( i )
236
+
237
+ const next = lines [ i + 1 ]
238
+ // found frontmatter, skip next dash
239
+ if ( line [ 3 ] !== '-' && next ?. trim ( ) ) {
240
+ start = i
241
+ for ( i += 1 ; i < lines . length ; i ++ ) {
242
+ if ( lines [ i ] . trimEnd ( ) === '---' )
243
+ break
244
+ }
245
+ contentStart = i + 1
246
+ }
247
+ }
248
+ // skip code block
249
+ else if ( line . trimStart ( ) . startsWith ( '```' ) ) {
250
+ const codeBlockLevel = line . match ( / ^ \s * ` + / ) ! [ 0 ]
251
+ let j = i + 1
252
+ for ( ; j < lines . length ; j ++ ) {
253
+ if ( lines [ j ] . startsWith ( codeBlockLevel ) )
254
+ break
255
+ }
256
+ // Update i only when code block ends
257
+ if ( j !== lines . length )
258
+ i = j
259
+ }
260
+ }
261
+
262
+ if ( start <= lines . length - 1 )
263
+ slice ( lines . length )
264
+
265
+ return {
266
+ filepath,
267
+ raw : markdown ,
268
+ slides,
269
+ }
270
+ }
271
+
198
272
function scanMonacoReferencedMods ( md : string ) {
199
273
const types = new Set < string > ( )
200
274
const deps = new Set < string > ( )
0 commit comments