Skip to content

Commit bd09530

Browse files
committed
feat: improve markdown parser
1 parent 30d682c commit bd09530

File tree

5 files changed

+66
-34
lines changed

5 files changed

+66
-34
lines changed

packages/slidev/node/parser.ts

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ function stringifySlide(data: SlideInfo, idx = 1) {
6969

7070
return (data.raw.startsWith('---') || idx === 0)
7171
? data.raw
72-
: `------\n${data.raw}`
72+
: `---\n${data.raw.startsWith('\n') ? data.raw : `\n${data.raw}`}`
7373
}
7474

7575
function prettifySlide(data: SlideInfo) {
@@ -96,8 +96,6 @@ export function parse(
9696
): SlidevMarkdown {
9797
const lines = markdown.split(/\n/g)
9898
const slides: SlideInfo[] = []
99-
let start = 0
100-
let dividers = 0
10199

102100
function parseContent(raw: string) {
103101
const result = matter(raw)
@@ -116,37 +114,40 @@ export function parse(
116114
}
117115
}
118116

119-
lines.forEach((line, i) => {
120-
line = line.trimRight()
121-
122-
if (line === '---')
123-
dividers += 1
124-
125-
// more than than 4 dashes
126-
const isHardDivider = !!line.match(/^----+$/)
127-
128-
if (dividers >= 3 || isHardDivider) {
129-
const end = i
130-
const raw = lines.slice(start, end).join('\n')
131-
slides.push({
132-
start,
133-
end,
134-
...parseContent(raw),
135-
})
136-
dividers = isHardDivider ? 2 : 1
137-
start = isHardDivider ? i + 1 : i
138-
}
139-
})
117+
let start = 0
140118

141-
if (start !== lines.length - 1) {
142-
const raw = lines.slice(start).join('\n')
119+
function slice(end: number) {
120+
if (start === end)
121+
return
122+
const raw = lines.slice(start, end).join('\n')
143123
slides.push({
144124
start,
145-
end: lines.length,
125+
end,
146126
...parseContent(raw),
147127
})
128+
start = end + 1
148129
}
149130

131+
for (let i = 0; i < lines.length; i++) {
132+
const line = lines[i].trimRight()
133+
if (line.match(/^---+$/)) {
134+
slice(i)
135+
136+
const next = lines[i + 1]
137+
// found frontmatter, skip next dash
138+
if (line.length === 3 && !next?.match(/^\s*$/)) {
139+
start = i
140+
for (i += 1; i < lines.length; i++) {
141+
if (lines[i].trimRight().match(/^---$/))
142+
break
143+
}
144+
}
145+
}
146+
}
147+
148+
if (start !== lines.length - 1)
149+
slice(lines.length - 1)
150+
150151
const headmatter = slides?.[0].frontmatter || {}
151152
const config: SlidevConfig = Object.assign({}, headmatter.config || {})
152153

test/__snapshots__/parser.test.ts.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ layout: center
2121
This is notes
2222
-->
2323
24-
------
24+
---
2525
2626
# Morning
2727
@@ -47,7 +47,7 @@ console.log('Hello World')
4747
\`\`\`
4848
4949
50-
------
50+
---
5151
5252
# Hello
5353
@@ -57,7 +57,7 @@ console.log('Hello World')
5757
- Yo
5858
5959
60-
------
60+
---
6161
6262
Nice to meet you
6363
"

test/fixtures/markdown/frontmatter.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ layout: center
1010
---
1111
# Hello
1212
<!-- This is notes -->
13-
------
13+
---
14+
1415
# Morning
1516
---
1617
layout: text

test/fixtures/markdown/minimal.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ Sample Text
88
console.log('Hello World')
99
```
1010

11-
------
11+
---
1212

1313
# Hello
1414

1515
- Hello
1616
- Hi
1717
- Hey
1818
- Yo
19-
------
19+
---
20+
2021
Nice to meet you

test/parser.test.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { resolve, basename } from 'path'
22
import fg from 'fast-glob'
3-
import { prettify, load, stringify } from '../packages/slidev/node'
3+
import { prettify, load, stringify, parse } from '../packages/slidev/node'
44

55
describe('md parser', () => {
66
const files = fg.sync('*.md', {
@@ -19,4 +19,33 @@ describe('md parser', () => {
1919
expect(stringify(data)).toMatchSnapshot('formatted')
2020
})
2121
}
22+
23+
it('parse', () => {
24+
const data = parse(`
25+
a
26+
27+
---
28+
29+
b
30+
31+
---
32+
layout: z
33+
---
34+
c
35+
----
36+
d
37+
----
38+
e
39+
40+
---
41+
42+
f
43+
44+
---
45+
`)
46+
expect(data.slides.map(i => i.content.trim()))
47+
.toEqual(Array.from('abcdef'))
48+
expect(data.slides[2].frontmatter)
49+
.toEqual({ layout: 'z' })
50+
})
2251
})

0 commit comments

Comments
 (0)