Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 47 additions & 2 deletions packages/parser/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,31 @@ export interface SlidevParserOptions {
preserveCR?: boolean
}

function advanceHtmlCommentState(line: string, inHtmlComment: boolean) {
let cursor = 0

while (cursor < line.length) {
if (inHtmlComment) {
const end = line.indexOf('-->', cursor)
if (end < 0)
return true
inHtmlComment = false
cursor = end + 3
}
else {
const start = line.indexOf('<!--', cursor)
if (start < 0)
return false
const end = line.indexOf('-->', start + 4)
if (end < 0)
return true
cursor = end + 3
}
}

return inHtmlComment
}

export function stringify(data: SlidevMarkdown) {
return `${data.slides.map(stringifySlide).join('\n').trim()}\n`
}
Expand Down Expand Up @@ -200,6 +225,7 @@ export async function parse(

let start = 0
let contentStart = 0
let inHtmlComment = false

async function slice(end: number) {
if (start === end)
Expand Down Expand Up @@ -247,7 +273,13 @@ export async function parse(
}

for (let i = 0; i < lines.length; i++) {
const line = lines[i].trimEnd()
const rawLine = lines[i]
const line = rawLine.trimEnd()
if (inHtmlComment) {
inHtmlComment = advanceHtmlCommentState(rawLine, true)
continue
}

if (line.startsWith('---')) {
await slice(i)

Expand All @@ -274,6 +306,9 @@ export async function parse(
if (j !== lines.length)
i = j
}
else {
inHtmlComment = advanceHtmlCommentState(rawLine, false)
}
}

if (start <= lines.length - 1)
Expand All @@ -296,6 +331,7 @@ export function parseSync(

let start = 0
let contentStart = 0
let inHtmlComment = false

function slice(end: number) {
if (start === end)
Expand All @@ -315,7 +351,13 @@ export function parseSync(
}

for (let i = 0; i < lines.length; i++) {
const line = lines[i].trimEnd()
const rawLine = lines[i]
const line = rawLine.trimEnd()
if (inHtmlComment) {
inHtmlComment = advanceHtmlCommentState(rawLine, true)
continue
}

if (line.startsWith('---')) {
slice(i)

Expand All @@ -342,6 +384,9 @@ export function parseSync(
if (j !== lines.length)
i = j
}
else {
inHtmlComment = advanceHtmlCommentState(rawLine, false)
}
}

if (start <= lines.length - 1)
Expand Down
35 changes: 35 additions & 0 deletions test/parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,41 @@ f
.toEqual({ })
})

it('ignores slide separators inside HTML comments', async () => {
const data = await parse(`---
src: ./pages/one.md
---

<!--
---
src: ./pages/two.md
---
-->

---
src: ./pages/three.md
---
`, 'slides.md')

expect(data.slides).toHaveLength(2)
expect(data.slides.map(slide => slide.frontmatter.src))
.toEqual(['./pages/one.md', './pages/three.md'])
})

it('detects slide separator even when comment opens on the same line', async () => {
const data = await parse(`a

----<!--
hidden
-->

b
`, 'file.md')

expect(data.slides).toHaveLength(2)
expect(data.slides.map(s => s.content.trim())).toEqual(['a', 'hidden\n-->\n\nb'])
})

async function parseWithExtension(
src: string,
transformRawLines: (lines: string[]) => void | Promise<void> = () => {},
Expand Down
Loading