Automerge backed Markdown editor for the Atmosphere
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889import { describe, expect, it } from 'vitest'import { markdownLanguage } from '@codemirror/lang-markdown'import { tokenClassNodeProp, reamsMarkdownLanguage } from '../markdown-language'
type NodeRange = { name: string; from: number; to: number }
function nodes(source: string, parser = reamsMarkdownLanguage.parser): NodeRange[] { const result: NodeRange[] = [] parser.parse(source).iterate({ enter: node => { result.push({ name: node.name, from: node.from, to: node.to }) }, }) return result}
function stockCodeContents(source: string): Array<{ from: number; to: number }> { const result: Array<{ from: number; to: number }> = [] markdownLanguage.parser.parse(source).iterate({ enter: node => { if (node.name !== 'InlineCode') return const first = node.node.firstChild const last = node.node.lastChild expect(first?.name).toBe('CodeMark') expect(last?.name).toBe('CodeMark') result.push({ from: first!.to, to: last!.from }) }, }) return result}
describe('reamsMarkdownLanguage inline-code compatibility', () => { const fixtures = [ 'plain text', '`= this.priority`', 'prefix `one` and `two` suffix', '``contains ` a backtick``', '` a leading and trailing space `', '`spans\ntwo lines`', '**`nested formatting`**', '[`inside a link`](https://example.com)', '# heading with `code`\n\n> quote with `code`\n\n- list with `code`', '| column |\n| --- |\n| `code` |', '[[wikilink]] next to `code` and ![[embed]]', '`unclosed code span', '``unequal ` delimiters', ]
it.each(fixtures)('preserves stock Lezer code-span recognition for %j', source => { const expected = stockCodeContents(source) const actual = nodes(source) .filter(node => node.name === 'InlineCode') .map(({ from, to }) => ({ from, to }))
expect(actual).toEqual(expected) })
it('changes only the inline-code container shape', () => { const source = 'before **`code`** [link](https://example.com) after' const stockStructure = nodes(source, markdownLanguage.parser) .filter(node => node.name !== 'InlineCode' && node.name !== 'CodeMark') const reamsStructure = nodes(source) .filter(node => node.name !== 'InlineCode' && node.name !== 'CodeMark')
expect(reamsStructure).toEqual(stockStructure) })
it('exposes content and delimiter token classes separately', () => { const source = '`= this.priority`' const tokenClasses: Array<{ text: string; tokenClass: string | undefined }> = [] reamsMarkdownLanguage.parser.parse(source).iterate({ enter: node => { if (node.name === 'InlineCode' || node.name === 'CodeMark') { tokenClasses.push({ text: source.slice(node.from, node.to), tokenClass: node.type.prop(tokenClassNodeProp), }) } }, })
expect(tokenClasses).toEqual([ { text: '`', tokenClass: 'formatting' }, { text: '= this.priority', tokenClass: 'inline-code' }, { text: '`', tokenClass: 'formatting' }, ]) })})