mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-28 05:11:24 +08:00
feat: add tests for YAML front matter tokenizer and enhance parsing logic
This commit is contained in:
parent
a8ded04eef
commit
daf5b7c5a1
@ -0,0 +1,84 @@
|
||||
import type { JSONContent } from '@tiptap/core'
|
||||
import { MarkdownManager } from '@tiptap/markdown'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { YamlFrontMatter } from '../yaml-front-matter'
|
||||
|
||||
const parseFrontMatters = (markdown: string) => {
|
||||
const manager = new MarkdownManager({
|
||||
extensions: [YamlFrontMatter]
|
||||
})
|
||||
const doc = manager.parse(markdown) as JSONContent
|
||||
const frontMatterNodes = (doc.content || []).filter((node) => node.type === 'yamlFrontMatter')
|
||||
return frontMatterNodes.map((node) => (node.attrs as { content?: string } | undefined)?.content?.trim())
|
||||
}
|
||||
|
||||
describe('YamlFrontMatter markdown tokenizer', () => {
|
||||
it('only parses the first front matter block at the very start of the document', () => {
|
||||
const markdown = `---
|
||||
title: First
|
||||
---
|
||||
|
||||
Body text
|
||||
|
||||
---
|
||||
title: Second
|
||||
---
|
||||
More content`
|
||||
|
||||
const contents = parseFrontMatters(markdown)
|
||||
expect(contents).toHaveLength(1)
|
||||
expect(contents[0]).toBe('title: First')
|
||||
})
|
||||
|
||||
it('ignores a front matter block when it is not at the beginning of the document', () => {
|
||||
const markdown = `Intro paragraph
|
||||
|
||||
---
|
||||
title: Should not parse
|
||||
---`
|
||||
|
||||
const contents = parseFrontMatters(markdown)
|
||||
expect(contents).toHaveLength(0)
|
||||
})
|
||||
|
||||
it('ignores consecutive front matter blocks after the first one', () => {
|
||||
const markdown = `---
|
||||
first: yes
|
||||
---
|
||||
---
|
||||
second: no
|
||||
---`
|
||||
|
||||
const contents = parseFrontMatters(markdown)
|
||||
expect(contents).toHaveLength(1)
|
||||
expect(contents[0]).toBe('first: yes')
|
||||
})
|
||||
|
||||
it('does not treat body content containing --- as additional front matter', () => {
|
||||
const markdown = `---
|
||||
title: Only header
|
||||
---
|
||||
|
||||
Paragraph text.
|
||||
|
||||
---
|
||||
|
||||
More text.`
|
||||
|
||||
const contents = parseFrontMatters(markdown)
|
||||
expect(contents).toHaveLength(1)
|
||||
expect(contents[0]).toBe('title: Only header')
|
||||
})
|
||||
|
||||
it('treats later front matter markers as regular markdown when content already exists', () => {
|
||||
const markdown = `Intro paragraph
|
||||
|
||||
---
|
||||
title: Should not parse
|
||||
---`
|
||||
|
||||
const contents = parseFrontMatters(markdown)
|
||||
expect(contents).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
@ -1,4 +1,4 @@
|
||||
import { mergeAttributes, Node } from '@tiptap/core'
|
||||
import { type MarkdownToken,mergeAttributes, Node } from '@tiptap/core'
|
||||
import { ReactNodeViewRenderer } from '@tiptap/react'
|
||||
|
||||
import YamlFrontMatterNodeView from '../components/YamlFrontMatterNodeView'
|
||||
@ -27,7 +27,12 @@ export const YamlFrontMatter = Node.create({
|
||||
return result
|
||||
},
|
||||
// Parse YAML front matter
|
||||
tokenize(src: string) {
|
||||
tokenize(src: string, tokens: MarkdownToken[] = []) {
|
||||
const hasExistingContent = tokens.some((token) => token.type && token.type !== 'space')
|
||||
if (hasExistingContent) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
// Match: ---\n...yaml content...\n---
|
||||
const match = /^---\n([\s\S]*?)\n---(?:\n|$)/.exec(src)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user