33 convertBlocksToMarkdown ,
44 convertTextContentToBlocks ,
55 convertTextToHTML ,
6- extractMarkdownLinks ,
76 isMarkdownFile ,
87} from '~/features/editor/utils/text-to-blocks'
98import type { CustomPartialBlock } from 'convex/notes/editorSpecs'
@@ -21,6 +20,12 @@ function getBlockText(block: CustomPartialBlock): string {
2120 . join ( '' )
2221}
2322
23+ type InlineContentItem = { type : string ; text ?: string ; styles ?: Record < string , boolean > }
24+
25+ function getInlineContent ( block : CustomPartialBlock ) : Array < InlineContentItem > {
26+ return ( block . content ?? [ ] ) as unknown as Array < InlineContentItem >
27+ }
28+
2429interface ExpectedBlock {
2530 type : string
2631 text ?: string
@@ -161,53 +166,6 @@ describe('isMarkdownFile', () => {
161166 } )
162167} )
163168
164- // ===========================================================================
165- // extractMarkdownLinks
166- // ===========================================================================
167-
168- describe ( 'extractMarkdownLinks' , ( ) => {
169- it ( 'replaces a regular markdown link with a placeholder' , ( ) => {
170- const { text, placeholders } = extractMarkdownLinks ( '[text](url)' )
171- expect ( placeholders . size ) . toBe ( 1 )
172- expect ( text ) . not . toContain ( '[text](url)' )
173- // Placeholder should map back to original
174- const [ , original ] = [ ...placeholders . entries ( ) ] [ 0 ]
175- expect ( original ) . toBe ( '[text](url)' )
176- } )
177-
178- it ( 'replaces an image link with a placeholder' , ( ) => {
179- const { text, placeholders } = extractMarkdownLinks ( '' )
180- expect ( placeholders . size ) . toBe ( 1 )
181- expect ( text ) . not . toContain ( '' )
182- const [ , original ] = [ ...placeholders . entries ( ) ] [ 0 ]
183- expect ( original ) . toBe ( '' )
184- } )
185-
186- it ( 'replaces multiple links on one line' , ( ) => {
187- const { placeholders } = extractMarkdownLinks ( '[a](b) and [c](d)' )
188- expect ( placeholders . size ) . toBe ( 2 )
189- } )
190-
191- it ( 'does not replace links inside code blocks' , ( ) => {
192- const input = '```\n[text](url)\n```'
193- const { text, placeholders } = extractMarkdownLinks ( input )
194- expect ( placeholders . size ) . toBe ( 0 )
195- expect ( text ) . toBe ( input )
196- } )
197-
198- it ( 'does not modify lines without links' , ( ) => {
199- const { text, placeholders } = extractMarkdownLinks ( 'plain text' )
200- expect ( placeholders . size ) . toBe ( 0 )
201- expect ( text ) . toBe ( 'plain text' )
202- } )
203-
204- it ( 'preserves wiki links [[name]]' , ( ) => {
205- const { text, placeholders } = extractMarkdownLinks ( '[[some note]]' )
206- expect ( placeholders . size ) . toBe ( 0 )
207- expect ( text ) . toBe ( '[[some note]]' )
208- } )
209- } )
210-
211169// ===========================================================================
212170// convertBlocksToMarkdown (export path)
213171// ===========================================================================
@@ -399,12 +357,7 @@ describe('convertTextContentToBlocks - markdown', () => {
399357 const blocks = md ( '**bold text**' )
400358 const para = blocks . find ( ( b ) => b . type === 'paragraph' )
401359 expect ( para ) . toBeDefined ( )
402- const content = para ! . content as unknown as Array < {
403- type : string
404- text ?: string
405- styles ?: Record < string , boolean >
406- } >
407- const boldItem = content . find ( ( ic ) => ic . styles ?. bold )
360+ const boldItem = getInlineContent ( para ! ) . find ( ( ic ) => ic . styles ?. bold )
408361 expect ( boldItem ) . toBeDefined ( )
409362 expect ( boldItem ! . text ) . toBe ( 'bold text' )
410363 } )
@@ -413,12 +366,7 @@ describe('convertTextContentToBlocks - markdown', () => {
413366 const blocks = md ( '*italic text*' )
414367 const para = blocks . find ( ( b ) => b . type === 'paragraph' )
415368 expect ( para ) . toBeDefined ( )
416- const content = para ! . content as unknown as Array < {
417- type : string
418- text ?: string
419- styles ?: Record < string , boolean >
420- } >
421- const italicItem = content . find ( ( ic ) => ic . styles ?. italic )
369+ const italicItem = getInlineContent ( para ! ) . find ( ( ic ) => ic . styles ?. italic )
422370 expect ( italicItem ) . toBeDefined ( )
423371 expect ( italicItem ! . text ) . toBe ( 'italic text' )
424372 } )
@@ -427,25 +375,15 @@ describe('convertTextContentToBlocks - markdown', () => {
427375 const blocks = md ( '~~struck~~' )
428376 const para = blocks . find ( ( b ) => b . type === 'paragraph' )
429377 expect ( para ) . toBeDefined ( )
430- const content = para ! . content as unknown as Array < {
431- type : string
432- text ?: string
433- styles ?: Record < string , boolean >
434- } >
435- const struckItem = content . find ( ( ic ) => ic . styles ?. strike )
378+ const struckItem = getInlineContent ( para ! ) . find ( ( ic ) => ic . styles ?. strike )
436379 expect ( struckItem ) . toBeDefined ( )
437380 } )
438381
439382 it ( 'parses inline code' , ( ) => {
440383 const blocks = md ( 'some `inline code` here' )
441384 const para = blocks . find ( ( b ) => b . type === 'paragraph' )
442385 expect ( para ) . toBeDefined ( )
443- const content = para ! . content as unknown as Array < {
444- type : string
445- text ?: string
446- styles ?: Record < string , boolean >
447- } >
448- const codeItem = content . find ( ( ic ) => ic . styles ?. code )
386+ const codeItem = getInlineContent ( para ! ) . find ( ( ic ) => ic . styles ?. code )
449387 expect ( codeItem ) . toBeDefined ( )
450388 expect ( codeItem ! . text ) . toBe ( 'inline code' )
451389 } )
@@ -512,7 +450,7 @@ describe('convertTextContentToBlocks - plain text', () => {
512450
513451 it ( 'preserves empty lines as empty paragraphs' , ( ) => {
514452 const blocks = txt ( 'A\n\nB' )
515- // Should have at least 3 blocks: A, empty, B (or A, B with spacing )
453+ // At least 2 blocks: A and B (parser may also insert an empty paragraph between them )
516454 expect ( blocks . length ) . toBeGreaterThanOrEqual ( 2 )
517455 const textsWithContent = blocks . filter ( ( b ) => getBlockText ( b ) !== '' )
518456 expect ( textsWithContent . length ) . toBe ( 2 )
0 commit comments